Android 全局异常上报

开始实现
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<String>() {
            @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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值