亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁技術文章
文章詳情頁

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

瀏覽:33日期:2022-09-21 10:48:38

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

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真的可行嗎?

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

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

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

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

Thread.setCaughtExceptionPreHandler()覆蓋所有線程,會在回調DefaultExceptionHandler之前調用; Thread.setCaughtExceptionHandler()同樣回覆蓋所有線程,可以在應用層被重復調用,并且每一次調用后,都會覆蓋上一次設置的DefaultUncaughtExceptionHandler; Thread.currentThread.setUncaughtExceptionHandler(),只可以覆蓋當前線程的異常。如果某個線程存在自定義的UncaughtExceptionHandler,回調時會忽略全局的DefaultUncaughtHandler。 既然話都說到這份上了,就請接下never crash大招吧。

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

有人可能要說了,你這樣catch住主線程的異常了,頁面可能要亂套哇。話雖如此,但你可以在catch中做業務保護呀。比如,我這里采取的做法是,關閉棧頂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住異常時,

//主線程出現異常,關閉棧頂activityActivityStack.Instance().curr()?.finish()github代碼

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

以上就是Android app會crash的原因及解決方法的詳細內容,更多關于Android app crash的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: 国产精品特黄一级国产大片 | 日本人一级毛片视频 | 青青热久久国产久精品秒播 | 亚洲综合欧美综合 | 久9视频这里只有精品 | 德国女人一级毛片免费 | 日韩在线一区二区三区免费视频 | 欧美性色大片 | 亚洲欧美日韩成人一区在线 | 久久久久欧美精品网站 | 久草在线视频精品 | 国产亚洲精品高清在线 | 亚州一级毛片 | 国产日本欧美高清免费区 | 99久免费精品视频在线观看2 | 91精品欧美一区二区三区 | 99久久精品免费看国产免费软件 | 欧美国产精品久久 | 国产精品九九九久久九九 | xx69欧美| 免费在线一级片 | 亚洲一级毛片欧美一级说乱 | 看一级特黄a大一片 | 99精品国产免费久久国语 | 亚洲欧美日韩在线观看二区 | 成人男女网18免费0 成人男女网18免费看 | 亚洲天堂视频在线免费观看 | 欧美日韩亚洲另类 | 99久久99热精品免费观看国产 | 日本韩国欧美在线观看 | 中文字幕精品视频 | 日韩精品中文字幕在线观看 | 亚洲成在| 免费国产成人综合 | 国产最猛性xxxxxx69交 | 中国国产一国产一级毛片视频 | 97在线碰碰观看免费高清 | 色综合久久久 | 国产精品揄拍一区二区 | 成人一区视频 | 91成人啪国产啪永久地址 |