11package com .wanjian .cockroach ;
22
3+ import android .os .Binder ;
34import android .os .Handler ;
45import android .os .Looper ;
56
67/**
78 * Created by wanjian on 2017/2/14.
8- * <p>
9- * 打不死的小强 , 永不crash的Android
109 */
1110
1211public final class Cockroach {
@@ -19,46 +18,72 @@ interface ExceptionHandler {
1918 private Cockroach () {
2019 }
2120
22- private static ExceptionHandler mExceptionHandler ;
21+ private static ExceptionHandler sExceptionHandler ;
22+ private static Thread .UncaughtExceptionHandler sUncaughtExceptionHandler ;
23+ private static boolean sInstalled = false ;//标记位,避免重复安装卸载
2324
2425 /**
2526 * 当主线程或子线程抛出异常时会调用exceptionHandler.handlerException(Thread thread, Throwable throwable)
2627 * <p>
2728 * exceptionHandler.handlerException可能运行在非UI线程中。
2829 * <p>
29- * handlerException内部建议手动try{ 你的异常处理逻辑 }catch(Throwable e){ } ,以防handlerException内部再次抛出异常,导致循环调用handlerException
30- * <p>
3130 * 若设置了Thread.setDefaultUncaughtExceptionHandler则可能无法捕获子线程异常。
3231 *
3332 * @param exceptionHandler
3433 */
35- public static void install (ExceptionHandler exceptionHandler ) {
36- mExceptionHandler = exceptionHandler ;
34+ public static synchronized void install (ExceptionHandler exceptionHandler ) {
35+ if (sInstalled ) {
36+ return ;
37+ }
38+ sInstalled = true ;
39+ sExceptionHandler = exceptionHandler ;
3740
3841 new Handler (Looper .getMainLooper ()).post (new Runnable () {
3942 @ Override
4043 public void run () {
44+
4145 while (true ) {
4246 try {
4347 Looper .loop ();
4448 } catch (Throwable e ) {
45- if (mExceptionHandler != null ) {
46- mExceptionHandler .handlerException (Looper .getMainLooper ().getThread (), e );
49+ // Binder.clearCallingIdentity();
50+ if (e instanceof QuitCockroachException ) {
51+ return ;
52+ }
53+ if (sExceptionHandler != null ) {
54+ sExceptionHandler .handlerException (Looper .getMainLooper ().getThread (), e );
4755 }
4856 }
4957 }
5058 }
5159 });
5260
53- // final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
61+ sUncaughtExceptionHandler = Thread .getDefaultUncaughtExceptionHandler ();
5462 Thread .setDefaultUncaughtExceptionHandler (new Thread .UncaughtExceptionHandler () {
5563 @ Override
5664 public void uncaughtException (Thread t , Throwable e ) {
57- if (mExceptionHandler != null ) {
58- mExceptionHandler .handlerException (t , e );
65+ if (sExceptionHandler != null ) {
66+ sExceptionHandler .handlerException (t , e );
5967 }
6068 }
6169 });
6270
6371 }
72+
73+ public static synchronized void uninstall () {
74+ if (!sInstalled ) {
75+ return ;
76+ }
77+ sInstalled = false ;
78+ sExceptionHandler = null ;
79+ //卸载后恢复默认的异常处理逻辑,否则主线程再次抛出异常后将导致ANR,并且无法捕获到异常位置
80+ Thread .setDefaultUncaughtExceptionHandler (sUncaughtExceptionHandler );
81+ new Handler (Looper .getMainLooper ()).post (new Runnable () {
82+ @ Override
83+ public void run () {
84+ throw new QuitCockroachException ("Quit Cockroach....." );//主线程抛出异常,迫使 while (true) {}结束
85+ }
86+ });
87+
88+ }
6489}
0 commit comments