一.問題拋出
android運行的時候難免會有一些空指針(NullPointerException)或者下標(biāo)越界(IndexOutOfBoundsException),用戶使用的過程操作某一個按鈕的時候,就發(fā)生了崩潰.這時候可能還沒有到他感興趣的部分,程序就Crash掉了,因此導(dǎo)致了用戶流失.如何讓程序在輕微異常情況下依然保持高可用
在集成一些第三方庫的時候,我們不能修改里面的實現(xiàn)(例如 Gson,FastJson,OkHttp,OkSocket,Glide)等,那么如果他們里面拋出異常如何解決,Glide加載圖片之后填充圖片時,如果Activity銷毀就會造成崩潰,那么我們?nèi)绾谓鉀Q?
二.解決效果
三.解決思路
- MainLooper一定要保證在崩潰的時候持續(xù)Loop
- 子線程發(fā)生崩潰,保證主線程Looper繼續(xù)Loop
- 當(dāng)繪制,測量,布局出現(xiàn)問題導(dǎo)致編舞者Crash時,應(yīng)該及時處理(關(guān)閉當(dāng)前異常的界面)
- 生命周期方法發(fā)生了異常,在ActivityThread里面hook其中的Instrumentation.進(jìn)行代理.
- 對ActivityThread中的mH 變量添加Callback,對于不能再Instrumentation中處理的異常進(jìn)行再次Catch.最大限度保證不崩潰.
四.成品Library
Github項目地址: https://github.com/xuuhaoo/Android-DefenseCrash (歡迎Star)
集成方法:
- Please add the code into your project gradle file
文檔 Android Defense Crash
為了方便中國同學(xué),提供了翻譯文檔如下:中文文檔
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()