最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android app會crash的原因及解決方法

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

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

Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));

如果沒有這句話,app就不會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());//殺死進程
        System.exit(10);
      }
    }
  } 

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

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

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

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

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

把android異常捕獲機制在梳理一下,熟悉的同學可以跳過,直接進入下一節(jié)。

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

既然話都說到這份上了,就請接下never crash大招吧。

要想不crash,只能讓線程不要拋出exception,唯此別無他法。如果我們能把一個線程的所有的操作都使用try-catch進行保護,理論上,就能做到app never crash。由于android基于Handler事件驅(qū)動的機制,可以在app啟動時,向主線程中的MessageQueue中提交一個死循環(huán)操作,在這個死循環(huán)中不斷去poll事件,并且將這個死循環(huán)進行try-catch,這樣所有主線程中的異常都會被catch住,從而app就再也不會發(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) {
          //所有主線程中的異常都會被catch住,從而不會發(fā)生crash
          Log.e(tag, "catch exception: " + e.message)
        }
      }
    }
  }

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

然后當catch住異常時,

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

github代碼

最后奉上github倉庫代碼,請笑納。

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

相關(guān)文章

  • 另外兩種Android沉浸式狀態(tài)欄實現(xiàn)思路

    另外兩種Android沉浸式狀態(tài)欄實現(xiàn)思路

    這篇文章主要為大家介紹了另外兩種Android沉浸式狀態(tài)欄實現(xiàn)思路,android5.0及以后版本都支持給狀態(tài)欄著色,而目前android主流版本還是4.4,想要深入了解的朋友可以參考一下
    2016-01-01
  • Flutter版本的自定義短信驗證碼實現(xiàn)示例解析

    Flutter版本的自定義短信驗證碼實現(xiàn)示例解析

    這篇文章主要介紹了Flutter版本的自定義短信驗證碼實現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Android開發(fā)-之五大布局詳解

    Android開發(fā)-之五大布局詳解

    這篇文章主要介紹了Android開發(fā)-之五大布局詳解,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • android實現(xiàn)音樂跳動效果的示例代碼

    android實現(xiàn)音樂跳動效果的示例代碼

    這篇文章主要介紹了android實現(xiàn)音樂跳動效果的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Android升級gradle 后引入aar包報錯解決

    Android升級gradle 后引入aar包報錯解決

    這篇文章主要為大家介紹了Android升級gradle 后引入aar包報錯解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Android Init進程對信號的處理流程詳細介紹

    Android Init進程對信號的處理流程詳細介紹

    這篇文章主要介紹了Android Init進程對信號的處理流程詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Android開發(fā)之音視頻協(xié)議介紹

    Android開發(fā)之音視頻協(xié)議介紹

    本文對音視頻的協(xié)議起源做詳細介紹,學習之后可以加深對音視頻知識的了解。這里的音視頻不僅針對Android平臺,其他平臺也通用。
    2022-04-04
  • Android進階CoordinatorLayout協(xié)調(diào)者布局實現(xiàn)吸頂效果

    Android進階CoordinatorLayout協(xié)調(diào)者布局實現(xiàn)吸頂效果

    這篇文章主要為大家介紹了Android進階CoordinatorLayout協(xié)調(diào)者布局實現(xiàn)吸頂效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Android列表動圖展示的實現(xiàn)策略

    Android列表動圖展示的實現(xiàn)策略

    這篇文章主要給大家介紹了關(guān)于Android列表動圖展示的實現(xiàn)策略的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • Android中捕獲全局異常實現(xiàn)代碼

    Android中捕獲全局異常實現(xiàn)代碼

    這篇文章主要介紹了Android中捕獲全局異常實現(xiàn)代碼,本文給出了2種方法,以及對應(yīng)實現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04

最新評論

延庆县| 镇平县| 繁峙县| 宁武县| 韶山市| 石嘴山市| 乐山市| 平凉市| 图片| 仁怀市| 疏勒县| 略阳县| 玛沁县| 麻栗坡县| 吉隆县| 万山特区| 贡山| 仪征市| 准格尔旗| 嘉善县| 霸州市| 清河县| 类乌齐县| 沂水县| 闽清县| 齐齐哈尔市| 清新县| 西充县| 涿州市| 信宜市| 苏尼特右旗| 霍邱县| 石河子市| 尼玛县| 延庆县| 寻乌县| 开鲁县| 永川市| 鹤岗市| 达孜县| 普兰店市|