欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android app會(huì)crash的原因及解決方法

 更新時(shí)間:2020年12月29日 10:30:32   作者:Android開(kāi)發(fā)中文站  
這篇文章主要介紹了Android app會(huì)crash的原因及解決方法,幫助大家更好的進(jìn)行Android開(kāi)發(fā),感興趣的朋友可以了解下

android main入口的commonInit()方法內(nèi)處,有這么一句話,

Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));

如果沒(méi)有這句話,app就不會(huì)crash。不信,你往里面看,

public KillApplicationHandler(LoggingHandler loggingHandler) {
 @Override
 public void uncaughtException(Thread t, Throwable e) {
 //捕獲到異常
   try {
     ......
     //打印crash日志,展示崩潰彈窗等
     // Bring up crash dialog, wait for it to be dismissed
     ActivityManager.getService().handleApplicationCrash(
       mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
      } catch (Throwable t2) {
        .... 
      } finally {
        // Try everything to make sure this process goes away.
        Process.killProcess(Process.myPid());//殺死進(jìn)程
        System.exit(10);
      }
    }
  } 

當(dāng)異常KillApplicationHandler捕獲到異常,進(jìn)行完一系列處理(主要是打印crash日志,通知AMS展示crash彈窗等)后,最終會(huì)殺死進(jìn)程,這樣你的app就崩潰了。

既然都崩潰了,自定義異常捕獲器來(lái)屏蔽crash真的可行嗎?

肯定有人會(huì)說(shuō),自定義一個(gè)異常捕獲器,來(lái)覆蓋掉系統(tǒng)的KillApplicationHandler,然后在捕獲到異常后,不殺進(jìn)程,app就不會(huì)崩潰了,就像下面這樣,

class MainApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    Thread.setDefaultUncaughtExceptionHandler { _, e ->
      //捕獲到異常,只打印日志,不殺進(jìn)程
      Log.e("MainApplication", "${Thread.currentThread().name} 捕獲到異常:${e.message}")
    }
  }
}

這其實(shí)只是隔壁老王的思路,雖然確實(shí)防護(hù)住子線程的crash,但是當(dāng)主線程出現(xiàn)異常時(shí),app還是無(wú)法正常運(yùn)行。這是因?yàn)?,?dāng)UncaughtExceptionHandler捕獲到線程拋出異常的時(shí)候,線程在執(zhí)行完uncaughtException()中的處理后,就無(wú)法繼續(xù)存活了。如果拋異常的線程是主線程,那就意味著主線程會(huì)死掉,這時(shí)你即便不殺進(jìn)程,進(jìn)程活著也沒(méi)有任何意義了,app還是會(huì)停止運(yùn)行。

把a(bǔ)ndroid異常捕獲機(jī)制在梳理一下,熟悉的同學(xué)可以跳過(guò),直接進(jìn)入下一節(jié)。

  • Thread.setCaughtExceptionPreHandler()覆蓋所有線程,會(huì)在回調(diào)DefaultExceptionHandler之前調(diào)用;
  • Thread.setCaughtExceptionHandler()同樣回覆蓋所有線程,可以在應(yīng)用層被重復(fù)調(diào)用,并且每一次調(diào)用后,都會(huì)覆蓋上一次設(shè)置的DefaultUncaughtExceptionHandler;
  • Thread.currentThread.setUncaughtExceptionHandler(),只可以覆蓋當(dāng)前線程的異常。如果某個(gè)線程存在自定義的UncaughtExceptionHandler,回調(diào)時(shí)會(huì)忽略全局的DefaultUncaughtHandler。

既然話都說(shuō)到這份上了,就請(qǐng)接下never crash大招吧。

要想不crash,只能讓線程不要拋出exception,唯此別無(wú)他法。如果我們能把一個(gè)線程的所有的操作都使用try-catch進(jìn)行保護(hù),理論上,就能做到app never crash。由于android基于Handler事件驅(qū)動(dòng)的機(jī)制,可以在app啟動(dòng)時(shí),向主線程中的MessageQueue中提交一個(gè)死循環(huán)操作,在這個(gè)死循環(huán)中不斷去poll事件,并且將這個(gè)死循環(huán)進(jìn)行try-catch,這樣所有主線程中的異常都會(huì)被catch住,從而app就再也不會(huì)發(fā)生crash。

private fun openCrashProtected() {
    Log.d(tag, "openCrashProtected")
    Handler(Looper.getMainLooper()).post {
      while (true) {
        try {
          Looper.loop()
          Log.d(tag, "main looper execute loop")
        } catch (e: Throwable) {
          //所有主線程中的異常都會(huì)被catch住,從而不會(huì)發(fā)生crash
          Log.e(tag, "catch exception: " + e.message)
        }
      }
    }
  }

有人可能要說(shuō)了,你這樣catch住主線程的異常了,頁(yè)面可能要亂套哇。話雖如此,但你可以在catch中做業(yè)務(wù)保護(hù)呀。比如,我這里采取的做法是,關(guān)閉棧頂activity。 解決ActivityLifeCycle,維護(hù)一個(gè)Activity棧,

private fun registerLifeCycle() {
    registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
      override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        ActivityStack.Instance().push(activity)
      }

      override fun onActivityResumed(activity: Activity) {
      }

      override fun onActivityStarted(activity: Activity) {
      }

      override fun onActivityPaused(activity: Activity) {

      }

      override fun onActivityDestroyed(activity: Activity) {
        ActivityStack.Instance().pop(activity)
      }

      override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

      }

      override fun onActivityStopped(activity: Activity) {
      }
    })
  }

然后當(dāng)catch住異常時(shí),

//主線程出現(xiàn)異常,關(guān)閉棧頂activity
ActivityStack.Instance().curr()?.finish()

github代碼

最后奉上github倉(cāng)庫(kù)代碼,請(qǐng)笑納。

以上就是Android app會(huì)crash的原因及解決方法的詳細(xì)內(nèi)容,更多關(guān)于Android app crash的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 解析Android框架之Volley源碼

    解析Android框架之Volley源碼

    我們知道Volley是在2013年Google I/O大會(huì)上推出了一個(gè)新的網(wǎng)絡(luò)通信框架,他的設(shè)計(jì)目的就是為了那些請(qǐng)求數(shù)據(jù)量不是特別大,但是又是特別頻繁的網(wǎng)絡(luò)操作非常適合。但是對(duì)于數(shù)據(jù)量較大的請(qǐng)求,比如說(shuō)下載一個(gè)較大的文件,Volley可能相比于其他的框架,就有點(diǎn)不足了。
    2021-06-06
  • Android4.0平板開(kāi)發(fā)之隱藏底部任務(wù)欄的方法

    Android4.0平板開(kāi)發(fā)之隱藏底部任務(wù)欄的方法

    這篇文章主要介紹了Android4.0平板開(kāi)發(fā)之隱藏底部任務(wù)欄的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android隱藏于顯示底部任務(wù)欄的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • Android編程實(shí)現(xiàn)畫(huà)板功能的方法總結(jié)【附源碼下載】

    Android編程實(shí)現(xiàn)畫(huà)板功能的方法總結(jié)【附源碼下載】

    這篇文章主要介紹了Android編程實(shí)現(xiàn)畫(huà)板功能的方法,結(jié)合實(shí)例形式總結(jié)分析了Android基于自定義View與Canvas類實(shí)現(xiàn)畫(huà)板功能的具體操作步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2018-02-02
  • myeclipse android環(huán)境搭建圖文教程

    myeclipse android環(huán)境搭建圖文教程

    在從事android應(yīng)用開(kāi)發(fā)過(guò)程中,搭配環(huán)境是所有開(kāi)始的第一步,本文將介紹myeclipse android環(huán)境搭建圖文教程,希望可以幫助大家完成android開(kāi)發(fā)之旅
    2012-11-11
  • Android微信第三方登錄(個(gè)人筆記)

    Android微信第三方登錄(個(gè)人筆記)

    這篇文章主要為大家詳細(xì)介紹了Android微信第三方登錄的具體過(guò)程,個(gè)人筆記分享,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Android開(kāi)發(fā)之在xml中設(shè)置自定義屬性的方法

    Android開(kāi)發(fā)之在xml中設(shè)置自定義屬性的方法

    下面小編就為大家分享一篇Android開(kāi)發(fā)之在xml中設(shè)置自定義屬性的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • Flutter?fluro時(shí)報(bào)錯(cuò)type?'String'?is?not?a?subtype?of?type?'Queue<Task>'

    Flutter?fluro時(shí)報(bào)錯(cuò)type?'String'?is?not?a?subty

    這篇文章主要介紹了Flutter使用fluro時(shí)報(bào)錯(cuò)type?'String'?is?not?a?subtype?of?type?'Queue<Task>'解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-12-12
  • Android strings.xml使用方法及技巧

    Android strings.xml使用方法及技巧

    本文主要介紹Android strings.xml,這里對(duì)strings.xml文件的使用和一些小技巧做了總結(jié),有興趣的同學(xué)可以看下
    2016-08-08
  • Android 仿微信小程序入口動(dòng)畫(huà)

    Android 仿微信小程序入口動(dòng)畫(huà)

    突然發(fā)現(xiàn)微信下拉小程序入口動(dòng)畫(huà)非常細(xì)膩,比較好奇,所以仿照他做了一個(gè),并不是很完美,部分效果還沒(méi)完成,但總體自我感覺(jué)還不錯(cuò),效果見(jiàn)下文
    2021-06-06
  • Android 實(shí)時(shí)監(jiān)測(cè)(監(jiān)聽(tīng))網(wǎng)絡(luò)連接狀態(tài)變化

    Android 實(shí)時(shí)監(jiān)測(cè)(監(jiān)聽(tīng))網(wǎng)絡(luò)連接狀態(tài)變化

    這篇文章主要介紹了Android 實(shí)時(shí)監(jiān)測(cè)(監(jiān)聽(tīng))網(wǎng)絡(luò)連接狀態(tài)變化的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-06-06

最新評(píng)論