一.问题抛出
android运行的时候难免会有一些空指针(NullPointerException)或者下标越界(IndexOutOfBoundsException),用户使用的过程操作某一个按钮的时候,就发生了崩溃.这时候可能还没有到他感兴趣的部分,程序就Crash掉了,因此导致了用户流失.如何让程序在轻微异常情况下依然保持高可用
在集成一些第三方库的时候,我们不能修改里面的实现(例如 Gson,FastJson,OkHttp,OkSocket,Glide)等,那么如果他们里面抛出异常如何解决,Glide加载图片之后填充图片时,如果Activity销毁就会造成崩溃,那么我们如何解决?
二.解决效果
三.解决思路
- MainLooper一定要保证在崩溃的时候持续Loop
- 子线程发生崩溃,保证主线程Looper继续Loop
- 当绘制,测量,布局出现问题导致编舞者Crash时,应该及时处理(关闭当前异常的界面)
- 生命周期方法发生了异常,在ActivityThread里面hook其中的Instrumentation.进行代理.
- 对ActivityThread中的mH 变量添加Callback,对于不能再Instrumentation中处理的异常进行再次Catch.最大限度保证不崩溃.
四.成品Library
Github项目地址: https://github.com/xuuhaoo/Android-DefenseCrash (欢迎Star)
集成方法:
- Please add the code into your project gradle file
文档 Android Defense Crash
为了方便中国同学,提供了翻译文档如下:中文文档
What's this
This’s a Crash Defense
library in Android to help you catch the Java exceptions
which you don’t expected.
Integration
- Step 1 Find the
build.gradle
file in your project and add the code into it as follow.
allprojects {
repositories {
//other mavens
maven(){
url "https://dl.bintray.com/xuuhaoo/maven"
}
}
}
- Step 2 Find the
build.gradle
file in the module that you want to integration
dependencies {
implementation 'com.tonystark.android:defense-crash:last.version’
}
Attentions:
last.version
is a substitute word, the real version will be found in [图片上传失败...(image-d56e40-1612263642898)]
Use
-
Initialize should be more earlier in application create, we suggest you put the init code in
Application
attachBaseContext(base:Context)
- Sample
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) DefenseCrash.initialize(this) ... }
-
Install Defense library after initialize.
- Sample
override fun attachBaseContext(base: Context) { super.attachBaseContext(base) DefenseCrash.initialize(this) DefenseCrash.install { thread, throwable, isSafeMode, isCrashInChoreographer -> //thread: The crash happened’s thread. //throwable: The Exception exactly is. //isSafeMode: If application is allready crashed and we saved it that is mean you are in safe mode, //that happens most of the time is your Main Looper is compromised by some errors and not going to normal,and we keep it runing that’s called safe mode. //isCrashInChoreographer: If crash happend in OnMeasure/OnLayout/OnDraw it will case screen blank or some view not draw successfully //If you got this true, we suggest you restart or finish the current Activity for good //You can throw some throwables here and if you do that, will case VM got this throwable and shutdown your process. //And you should do somting here such as: Log.i("Exceptionhandler", "thread:${thread.name} " + "exception:${throwable.message} " + "isCrashInChoreographer:$isCrashInChoreographer " + "isSafeMode:$isSafeMode") throwable.printStackTrace() FirebaseCrashlytics.getInstance().recordException(throwable); } }
-
Uninstall Defense library if you don’t need this.
- Sample
DefenseCrash.unInstall()