android-notes / Cockroach

降低Android非必要crash
MIT License
3.25k stars 449 forks source link

捕获到异常之后无响应 #2

Closed Reginer closed 7 years ago

Reginer commented 7 years ago

在Activity初始化的时候就抛出一个异常直接就卡死了 。

比如这样 findViewById(R.id.tv_title).setOnClickListener(this); 这个tv_title不在setContentView(R.layout.activity_main)的activity_main里面。 就不行了。

android-notes commented 7 years ago

可以贴一下完整代码吗?是不是没有在findViewById前装载Cockroach,又或者在其他地方设置了Thread.setDefaultUncaughtExceptionHandler

Reginer commented 7 years ago

@android-notes 代码我传到云盘了,app目录下有个测试的apk。 http://pan.baidu.com/s/1i4NIRIX 看下是否是bug,或者是我写的有问题。

android-notes commented 7 years ago

可以贴一下 异常日志吗

Reginer commented 7 years ago

application public class App extends Application {

@Override
public void onCreate() {
    super.onCreate();
    initCrash();
}

private void initCrash() {
    Cockroach.install(new Cockroach.ExceptionHandler() {
        @Override
        public void handlerException(Thread thread, final Throwable throwable) {
            Writer writer = new StringWriter();
            PrintWriter pw = new PrintWriter(writer);
            throwable.printStackTrace(pw);
            Log.e("error", "error is:" + writer.toString());
        }
    });
}

}

错误日志 error: error is:java.lang.RuntimeException: Unable to start activity ComponentInfo{xyz.reginer.crash/xyz.reginer.crash.Main2Activity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2534) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2608) at android.app.ActivityThread.access$800(ActivityThread.java:178) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:194) at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5637) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at xyz.reginer.crash.Main2Activity.initView(Main2Activity.java:18) at xyz.reginer.crash.Main2Activity.onCreate(Main2Activity.java:14) at android.app.Activity.performCreate(Activity.java:6092) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2481) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2608)  at android.app.ActivityThread.access$800(ActivityThread.java:178)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)  at android.os.Handler.dispatchMessage(Handler.java:111)  at android.os.Looper.loop(Looper.java:194)  at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47)  at android.os.Handler.handleCallback(Handler.java:815)  at android.os.Handler.dispatchMessage(Handler.java:104)  at android.os.Looper.loop(Looper.java:194)  at android.app.ActivityThread.main(ActivityThread.java:5637)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754) 

android-notes commented 7 years ago

日志中有 at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47) 就说明被拦截到了,因为activity初始化时抛出了异常,导致生命周期不完整,所以就导致没反应了,但进程并没有重启,这个方案只能保证activity不闪退,进程不重启。有些时候抛出异常对用户时没影响的,比如点击view时抛出了异常,你的点击逻辑当然不会执行,用户的感觉就是没点到,再比如给recycleerview设置数据时抛出了异常,只有滚到到抛出异常的位置时才没法继续往下滚动,其他位置的view都是正常的,可以保证点击等都有相应

Reginer commented 7 years ago

那这框架还有提高的空间么 ?

android-notes commented 7 years ago

只要主线程某个方法处抛出异常则整个函数调用栈就会终止,这点是没法改变的,异常会层层上抛,直到最后被Cockroach捕获。你的逻辑到底要怎样执行Cockroach不清楚,也没法对其修复,Cockroach最主要的功能是用来保证activity不闪退,进程不重启,至于被Cockroach拦截后倒地会发送什么Cockroach不清楚。Cockroach一般可以用作捕获view 点击时抛出的异常,以及new handler发送消息时的异常,revyvlerview等的异常。其他的异常虽然Cockroach也可以拦截,拦截后有可能对用户没有影响,不影响ui,也有可能影响ui

Reginer commented 7 years ago

jeffery812 commented 7 years ago

漂亮 !