Android(安卓)全局异常上报
16lz
2021-12-04
开始实现
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、捕获异常
@Overridepublic 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
更多相关文章
- android之activity间传输数据
- 视力测试Demo
- Android(安卓): Spinner初始化时填充默认值数据
- 打开android默认浏览器
- Android(安卓): Spinner初始化时填充默认值数据
- Android(安卓)EditText 密码框默认是小圆点 怎么改成其它的(*)?
- android log日志
- 关于android studio启动时加载项目gradle build出现错误的解决方
- 图标集合-系统默认