package com.shayu.phonelive; import android.app.Application; import android.os.Handler; import android.os.Looper; import android.util.Log; /** * @ClassName NeverCrashUtils * @Description 全局捕获异常 */ public class NeverCrashUtils { private final static String TAG = NeverCrashUtils.class.getSimpleName(); private final static NeverCrashUtils INSTANCE = new NeverCrashUtils(); private boolean debugMode; private MainCrashHandler mainCrashHandler; private UncaughtCrashHandler uncaughtCrashHandler; private NeverCrashUtils() { } public static NeverCrashUtils getInstance() { return INSTANCE; } private synchronized MainCrashHandler getMainCrashHandler() { if (null == mainCrashHandler) { mainCrashHandler = (t, e) -> { }; } return mainCrashHandler; } /** * 主线程发生异常时的回调,可用于打印日志文件 *
* 注意跨线程操作的可能 */ public NeverCrashUtils setMainCrashHandler(MainCrashHandler mainCrashHandler) { mainCrashHandler = mainCrashHandler; return this; } private synchronized UncaughtCrashHandler getUncaughtCrashHandler() { if (null == uncaughtCrashHandler) { uncaughtCrashHandler = (t, e) -> { }; } return uncaughtCrashHandler; } /** * 子线程发生异常时的回调,可用于打印日志文件 *
* 注意跨线程操作的可能 */ public NeverCrashUtils setUncaughtCrashHandler(UncaughtCrashHandler uncaughtCrashHandler) { this.uncaughtCrashHandler = uncaughtCrashHandler; return this; } private boolean isDebugMode() { return debugMode; } /** * debug模式,会打印log日志,且toast提醒发生异常,反之则都没有 */ public NeverCrashUtils setDebugMode(boolean debugMode) { this.debugMode = debugMode; return this; } /** * 完成监听异常的注册 * @param application application */ public void register(Application application) { //主线程异常拦截 new Handler(Looper.getMainLooper()).post(() -> { while (true) { try { Looper.loop(); } catch (Throwable e) { if (isDebugMode()) { Log.e(TAG, "未捕获的主线程异常行为", e); } getMainCrashHandler().mainException(Looper.getMainLooper().getThread(), e); } } }); //子线程异常拦截 Thread.setDefaultUncaughtExceptionHandler((t, e) -> { if (isDebugMode()) { Log.e(TAG, "未捕获的子线程异常行为", e); } getUncaughtCrashHandler().uncaughtException(t, e); }); } public interface MainCrashHandler { void mainException(Thread t, Throwable e); } public interface UncaughtCrashHandler { void uncaughtException(Thread t, Throwable e); } }