对于Android 异常退出,主要是用到了 接口Thread.UncaughtExceptionHandler
public class MyApplication extends Application {
ErrorReport errorReport;
@Override
public void onCreate() {
super.onCreate();
errorReport = new ErrorReport(this);
}
}
public class ErrorReport implements Thread.UncaughtExceptionHandler{
public static final String TAG = "GouMinErrorReport";
private Context mContext;
// 系统默认的 UncaughtException 处理类
private Thread.UncaughtExceptionHandler mDefaultHandler;
private String logStr;
public ErrorReport(Context context) {
mContext = context;
// 获取系统默认的 UncaughtException 处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
GMLog.i(TAG, "uncaughtException");
GMLog.i(TAG, ex.getLocalizedMessage());
ex.printStackTrace();
logStr = getStackTrace(ex);
// 使用 Toast 来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出。", Toast.LENGTH_SHORT)
.show();
sendReport(logStr);
Looper.loop();
}
}.start();
// 如果用户没有处理则让系统默认的异常处理器来处理
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
}
}
private void sendReport(String stackTrace) {
GMLog.i(TAG, "sendReport");
HttpClient httpclient = new DefaultHttpClient();
final HttpPost httppost = new HttpPost(mErrorReportReq.getUrl());
try {
httppost.setEntity(new StringEntity(stackTrace) ));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
HttpResponse httpResponse;
try {
httpResponse = httpclient.execute(httppost);
final int statusCode = httpResponse.getStatusLine().getStatusCode();
GMLog.i(TAG, "sendReport response statusCode is:" + statusCode);
if (statusCode == HttpStatus.SC_OK) {
String response = EntityUtils.toString(
httpResponse.getEntity(), HTTP.UTF_8);
GMLog.i(TAG, "sendReport response:" + response);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
GMLog.i(TAG, "sendReport finally");
if (httpclient != null) {
httpclient.getConnectionManager().shutdown();
httpclient = null;
}
}
}
private String getStackTrace(Throwable th) {
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
// If the exception was thrown in a background thread inside
// AsyncTask, then the actual exception can be found with getCause
Throwable cause = th;
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
final String stacktraceAsString = result.toString();
printWriter.close();
return stacktraceAsString;
}
}
https://github.com/ACRA/acra
https://github.com/ACRA/acra/wiki/AdvancedUsage#data-encoding-formjson
http://blog.youkuaiyun.com/moruite/article/details/7397000
http://www.cnblogs.com/lee0oo0/archive/2012/11/28/2793052.html