All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mobi.cangol.mobile.service.crash.CrashServiceImpl Maven / Gradle / Ivy

There is a newer version: 1.2.7
Show newest version
/**
 * Copyright (c) 2013 Cangol
 * 

* Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package mobi.cangol.mobile.service.crash; import android.annotation.TargetApi; import android.app.Application; import android.os.Build; import android.os.StrictMode; import android.text.TextUtils; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; import java.util.ArrayList; import java.util.List; import java.util.Map; import mobi.cangol.mobile.CoreApplication; import mobi.cangol.mobile.Task; import mobi.cangol.mobile.http.AsyncHttpClient; import mobi.cangol.mobile.http.AsyncHttpResponseHandler; import mobi.cangol.mobile.http.RequestParams; import mobi.cangol.mobile.logging.Log; import mobi.cangol.mobile.service.AppService; import mobi.cangol.mobile.service.PoolManager; import mobi.cangol.mobile.service.Service; import mobi.cangol.mobile.service.ServiceProperty; import mobi.cangol.mobile.service.conf.ConfigService; import mobi.cangol.mobile.service.session.SessionService; import mobi.cangol.mobile.utils.DeviceInfo; import mobi.cangol.mobile.utils.FileUtils; import mobi.cangol.mobile.utils.Object2FileUtils; import mobi.cangol.mobile.utils.TimeUtils; /** * @author Cangol */ @Service("CrashService") class CrashServiceImpl implements CrashService, UncaughtExceptionHandler { private static final String TAG = "CrashService"; private static final String CRASH = ".crash"; private boolean debug = true; private Thread.UncaughtExceptionHandler mDefaultExceptionHandler; private CoreApplication mApplication; private SessionService mSessionService; private ServiceProperty mServiceProperty = null; private AsyncHttpClient asyncHttpClient; private String mUrl; private Map mParams; private String mCrashDir; @TargetApi(Build.VERSION_CODES.GINGERBREAD) @Override public void onCreate(Application context) { mApplication = (CoreApplication) context; mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); mSessionService = (SessionService) mApplication.getAppService(AppService.SESSION_SERVICE); final ConfigService configService = (ConfigService) mApplication.getAppService(AppService.CONFIG_SERVICE); mCrashDir = configService.getTempDir().getAbsolutePath() + File.separator + "crash"; final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); FileUtils.newFolder(mCrashDir); StrictMode.setThreadPolicy(oldPolicy); } @Override public void init(ServiceProperty serviceProperty) { this.mServiceProperty = serviceProperty; PoolManager.buildPool(mServiceProperty.getString(CRASHSERVICE_THREADPOOL_NAME), mServiceProperty.getInt(CRASHSERVICE_THREAD_MAX)); asyncHttpClient = AsyncHttpClient.build(mServiceProperty.getString(CRASHSERVICE_THREADPOOL_NAME)); } @Override public String getName() { return TAG; } @Override public void onDestroy() { asyncHttpClient.cancelRequests(mApplication, true); } @Override public void setDebug(boolean mDebug) { this.debug = mDebug; } @Override public ServiceProperty getServiceProperty() { return mServiceProperty; } @Override public ServiceProperty defaultServiceProperty() { final ServiceProperty sp = new ServiceProperty(TAG); sp.putString(CRASHSERVICE_THREADPOOL_NAME, TAG); sp.putInt(CRASHSERVICE_THREAD_MAX, 1); sp.putString(CRASHSERVICE_REPORT_URL, ""); sp.putString(CRASHSERVICE_REPORT_ERROR, "error"); sp.putString(CRASHSERVICE_REPORT_POSITION, "position"); sp.putString(CRASHSERVICE_REPORT_TIMESTAMP, "timestamp"); sp.putString(CRASHSERVICE_REPORT_CONTEXT, "content"); sp.putString(CRASHSERVICE_REPORT_FATAL, "fatal"); return sp; } @Override public void setReport(String url, Map params) { this.mUrl = url; this.mParams = params; } private void report(final ReportError report) { if (debug) { Log.d(TAG, "report .crash " + report.path); } final RequestParams params = this.mParams == null ? new RequestParams() : new RequestParams(this.mParams); params.put(mServiceProperty.getString(CRASHSERVICE_REPORT_ERROR), report.error); params.put(mServiceProperty.getString(CRASHSERVICE_REPORT_POSITION), report.position); params.put(mServiceProperty.getString(CRASHSERVICE_REPORT_CONTEXT), report.context); params.put(mServiceProperty.getString(CRASHSERVICE_REPORT_TIMESTAMP), report.timestamp); params.put(mServiceProperty.getString(CRASHSERVICE_REPORT_FATAL), report.fatal); asyncHttpClient.post(mApplication, mUrl, params, new AsyncHttpResponseHandler() { @Override public void onStart() { //do nothings } @Override public void onSuccess(String content) { super.onSuccess(content); mApplication.post(new Runnable() { @Override public void run() { FileUtils.delFile(report.path); } }); } @Override public void onFailure(Throwable error, String content) { //do nothings } }); } protected String throwableToString(Throwable ex) { final Writer writer = new StringWriter(); final PrintWriter pw = new PrintWriter(writer); ex.printStackTrace(pw); pw.close(); return writer.toString(); } protected ReportError makeReportError(Throwable ex) { final String timestamp = TimeUtils.getCurrentTime(); final String filename = timestamp.replaceAll(" ", "").replaceAll("-", "").replaceAll(":", ""); final ReportError error = new ReportError(); error.error = ex.toString(); error.position = ex.getStackTrace()[0].toString(); error.context = throwableToString(ex); error.timestamp = timestamp; error.fatal = "0"; error.path = mCrashDir + File.separator + filename + CRASH; return error; } @Override public void uncaughtException(Thread thread, Throwable ex) { Thread.setDefaultUncaughtExceptionHandler(mDefaultExceptionHandler); final ReportError error = makeReportError(ex); Log.e("AndroidRuntime", error.context); if (debug) { Log.d(TAG, "save .crash " + error.path); } Object2FileUtils.writeObject(error, error.path); mSessionService.saveString("exitCode", "1"); mSessionService.saveString("exitVersion", DeviceInfo.getAppVersion(mApplication)); //0 正常推退出 1异常退出 System.exit(0); } @Override public void report(final CrashReportListener crashReportListener) { mApplication.post(new Task>() { @Override public List call() { final List files = FileUtils.searchBySuffix(new File(mCrashDir), null, CRASH); final List reports = new ArrayList<>(); Object obj = null; for (final File file : files) { obj = FileUtils.readObject(file); if (obj != null) { reports.add((ReportError) obj); } else { FileUtils.delFile(file.getAbsolutePath()); } } return reports; } @Override public void result(List result) { for (final ReportError errorReport : result) { if (!TextUtils.isEmpty(mUrl)) { report(errorReport); } if (crashReportListener != null) { crashReportListener.report(errorReport.path, errorReport.error, errorReport.position, errorReport.context, errorReport.timestamp, errorReport.fatal); } } } }); } static class ReportError implements java.io.Serializable { private static final long serialVersionUID = 0L; String error; String position; String context; String timestamp; String fatal; String path; ReportError() { } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy