如何優(yōu)雅的避免Android(安卓)運行時崩潰,保證程序高可用

一.問題拋出

  • android運行的時候難免會有一些空指針(NullPointerException)或者下標(biāo)越界(IndexOutOfBoundsException),用戶使用的過程操作某一個按鈕的時候,就發(fā)生了崩潰.這時候可能還沒有到他感興趣的部分,程序就Crash掉了,因此導(dǎo)致了用戶流失.如何讓程序在輕微異常情況下依然保持高可用

  • 在集成一些第三方庫的時候,我們不能修改里面的實現(xiàn)(例如 Gson,FastJson,OkHttp,OkSocket,Glide)等,那么如果他們里面拋出異常如何解決,Glide加載圖片之后填充圖片時,如果Activity銷毀就會造成崩潰,那么我們?nèi)绾谓鉀Q?

二.解決效果

預(yù)防崩潰演示效果圖.gif

三.解決思路

  • 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.versionis 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()
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容