开始实现
1、实现Thread.UncaughtExceptionHandler接口
public class ExceptionHelper implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
}
}
2、单例模式
private static volatile ExceptionHelper INSTANCE;
private ExceptionHelper() {}
public static ExceptionHelper getInstance() {
if (INSTANCE == null) {
synchronized (ExceptionHelper.class) {
if (INSTANCE == null) {
synchronized (ExceptionHelper.class) {
INSTANCE = new ExceptionHelper();
}
}
}
}
return INSTANCE;
}
3、初始化异常信息
private Thread.UncaughtExceptionHandler mDefaultHandler;
public void init() {
// 获取默认异常处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 将当前类设为默认异常处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
4、捕获异常
@Override
public void uncaughtException(Thread t, Throwable e) {
if (handlerException(e)) {
// 未处理异常,调用系统方法来进行处理,弹出错误弹框或闪退
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(t, e);
}
} else {
// 拦截错误,可进行重启APP等后续操作
}
}
private boolean handleException(Throwable e) {
if (e == null) {
return false;
}
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
pw.close();
String result = writer.toString();
Log.e("TAG", result);
return true;
}
5、在App中初始化
public class App extends Application {
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
// 初始化ExceptionHelper
ExceptionHelper.getInstance().init();
}
public static Context getContext() {
return mContext;
}
}
测试
在启动Activity中调用 int a = 1 / 0。APP没有闪退,也没有弹出错误提示。收集到的错误日志如下:
E/TAG:java.lang.ArithmeticException: divide by zero
at com.lbj.mvpflower.mvp.ui.activity.UserActivity.onUser(UserActivity.java:36)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4702)
at android.view.View.performClick(View.java:5619)
at android.view.View$PerformClick.run(View.java:22298)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:165)
at android.app.ActivityThread.main(ActivityThread.java:6365)
完整代码
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.bcm.havoc.mylibrary.Application.URLConfig;
import com.bcm.havoc.mylibrary.Utils.ToastUtil;
import com.bcm.havoc.mylibrary.Utils.logger.Logger;
import com.bcm.havoc.pdabale_20190603.Entity.ErrorMessage;
import com.google.gson.Gson;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
/**
* @Author misolamiso.
* @Date 2019/11/15-8:55
*/
public class ExceptionHelper implements Thread.UncaughtExceptionHandler {
private static volatile ExceptionHelper INSTANCE;
private ExceptionHelper() {
}
public static ExceptionHelper getInstance() {
if (INSTANCE == null) {
synchronized (ExceptionHelper.class) {
if (INSTANCE == null) {
synchronized (ExceptionHelper.class) {
INSTANCE = new ExceptionHelper();
}
}
}
}
return INSTANCE;
}
private Thread.UncaughtExceptionHandler mDefaultHandler;
/**
* 初始化默认异常捕获
*/
public void init() {
// 获取默认异常处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 将当前类设为默认异常处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
if (handleException(e)) {
// 已经处理,APP重启
// restartApp();
} else {
// 如果不处理,则调用系统默认处理异常,弹出系统强制关闭的对话框
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(t, e);
}
}
}
private boolean handleException(Throwable e) {
if (e == null) {
return false;
}
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
pw.close();
String result = writer.toString();
// 打印出错误日志
ToastUtil.showToast("很抱歉,程序出现异常,即将退出,具体错误已发送到后台管理人员");
Logger.e(result);
SendErroe(e.getMessage()+"",result);
return true;
}
/**
* 1s后让APP重启
*/
private void restartApp() {
Intent intent = MyApplication.getContext().getPackageManager()
.getLaunchIntentForPackage(MyApplication.getContext().getPackageName());
PendingIntent restartIntent = PendingIntent.getActivity(MyApplication.getContext(), 0, intent, 0);
AlarmManager mgr = (AlarmManager) MyApplication.getContext().getSystemService(Context.ALARM_SERVICE);
// 1秒钟后重启应用
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent);
System.exit(0);
}
/**
* 向服务端发送错误异常
*
* @Event(type = View.OnLongClickListener.class,value = R.id.bt_main)
* private boolean testOnLongClickListener(View v){
* Snackbar.make(v,"testOnLongClickListener",Snackbar.LENGTH_SHORT).show();
* return true;
* }
*/
private void SendErroe(String excepMessage, String result) {
Gson gson = new Gson();
MyApplication application = MyApplication.getInstance();
ErrorMessage errorMessage = new ErrorMessage(application.getUserid()+"",excepMessage,result+"");
RequestParams params = new RequestParams(URLConfig.CottonException);
String RequestStr = gson.toJson(errorMessage);
params.setAsJsonContent(true);
params.setBodyContent(RequestStr);
params.setCharset("UTF-8");
Logger.e(params+RequestStr);
x.http().post(params, new Callback.ProgressCallback() {
@Override
public void onWaiting() {
}
@Override
public void onStarted() {
}
@Override
public void onLoading(long total, long current, boolean isDownloading) {
}
@Override
public void onSuccess(String result) {
Logger.d(result);
// SystemUsers Entity = JsonUtils.getPerson(result, SystemUsers.class);
// Logger.i("getMsg:" + Entity.getMessage() + "");
// if (Entity.getMessage().equals("OK")) {
// //写缓存
// application.setUserLoginMainEntity(Entity.getData());
// aCache.put(MyApplication.userinfo, (Serializable) Entity.getData());
// //跳转物流上下车
// Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
// Logger.d(Entity.getData());
// startActivity(intent);
// } else {
// et_User.setText("");
// et_Password.setText("");
// Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
// }
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
ex.printStackTrace();
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
}
参考https://www.jianshu.com/p/d28d9a7bdb1d