android-notes

Cockroach

降低Android非必要crash
Under MIT License
By android-notes

crash android

Cockroach 2.0
为什么开发这个库

很多时候由于一些微不足道的bug导致app崩溃很可惜,android默认的异常杀进程机制简单粗暴,但很多时候让app崩溃其实也并不能解决问题。


有些bug可能是系统bug,对于这些难以预料的系统bug我们不好绕过,还有一些bug是我们自己编码造成的,对于有些bug来说直接忽略掉的话可能只是导致部分不重要的功能没法使用而已,又或者对用户来说完全没有影响,这种情况总比每次都崩溃要好很多。


下面介绍几个真实案例来说明这个库的优势:



API28 ContextImpl startActivity源码
```java
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();


    // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
// generally not allowed, except if the caller specifies the task id the activity should
// be launched in. A bug was existed between N and O-MR1 which allowed this to work. We
// maintain this for backwards compatibility.
final int targetSdkVersion = getApplicationInfo().targetSdkVersion;

if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& (targetSdkVersion < Build.VERSION_CODES.N
|| targetSdkVersion >= Build.VERSION_CODES.P)
&& (options == null
|| ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}


```



更新日志

cockroach1.0版在这


Cockroach 2.0新特性

用一张图片来形容就是




特别注意: 当view的measure,layout,draw,以及recyclerview的bindviewholder 方法抛出异常时会导致
viewrootimpl挂掉,此时会回调 onMayBeBlackScreen 方法,建议直接杀死app。目前可以拦截到抛出异常的ViewRootImpl,具体参考这https://github.com/android-notes/SwissArmyKnife/blob/master/saklib/src/main/java/com/wanjian/sak/system/traversals/ViewTraversalsCompact.java



使用姿势

例如:


```java


package com.wanjian.demo;

import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.wanjian.cockroach.Cockroach;

/**
* Created by wanjian on 2018/5/19.
*/

public class App extends Application {

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

private void install() {
Cockroach.install(new ExceptionHandler() {
@Override
protected void onUncaughtExceptionHappened(Thread thread, Throwable throwable) {
Log.e("AndroidRuntime", "--->onUncaughtExceptionHappened:" + thread + "<---", throwable);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
toast.setText(R.string.safe_mode_excep_tips);
toast.show();
}
});
}

@Override
protected void onBandageExceptionHappened(Throwable throwable) {
throwable.printStackTrace();//打印警告级别log,该throwable可能是最开始的bug导致的,无需关心
toast.setText("Cockroach Worked");
toast.show();
}

@Override
protected void onEnterSafeMode() {
int tips = R.string.safe_mode_tips;
Toast.makeText(App.this, getResources().getString(tips), Toast.LENGTH_LONG).show();

}

@Override
protected void onMayBeBlackScreen(Throwable e) {
Thread thread = Looper.getMainLooper().getThread();
Log.e("AndroidRuntime", "--->onUncaughtExceptionHappened:" + thread + "<---", e);
//黑屏时建议直接杀死app
sysExcepHandler.uncaughtException(thread, new RuntimeException("black screen"));
}

});

}
}


```


原理分析

cockroach2.0通过替换ActivityThread.mH.mCallback,实现拦截Activity生命周期,
通过调用ActivityManager的finishActivity结束掉生命周期抛出异常的Activity


相关视频
https://github.com/android-notes/Cockroach/blob/master/cockroach.mp4?raw=true


相关原理分析


相关连接