新聞中心
問答環(huán)節(jié)

晉州網站建設公司創(chuàng)新互聯建站,晉州網站設計制作,有大型網站制作公司豐富經驗。已為晉州上千余家提供企業(yè)網站建設服務。企業(yè)網站搭建\外貿網站建設要多少錢,請找那個售后服務好的晉州做網站的公司定做!
問:Android 主線程崩潰與子線程崩潰有什么本質區(qū)別?
答:子線程崩潰就是正常的 Java thread 樣子,通過 setDefaultUncaughtExceptionHandler 就能捕獲 ThreadGroup 里對應子線程的異常做后續(xù)處理(啟動獨立進程提醒用戶并上報平臺等,或者通過策略下發(fā)忽略特定異常當作沒發(fā)生一樣)。安卓中主線程的 Crash 和子線程 Crash 有一點差異,雖然本質都是通過 setDefaultUncaughtExceptionHandler 就能捕獲,但是這背后其實是有一點竅門的。由于 Android 主線程啟動后通過 MainHandler 的 Looper.loop() 一直保持管道阻塞式的生產消費者死循環(huán),所有的主線程代碼都是通過這個循環(huán)派發(fā)在 MainLooper 中執(zhí)行的,所以當主線程 crash 的場景下,這個循環(huán)會被跳出,導致 Looper 無法再繼續(xù)執(zhí)行其中的其他 Message,所以當主線程 crash 時會出現幾種不同的表現,場景的一種就是在 Activity 的 onCreate 中 crash 會導致界面黑屏(注意,這種 crash 不是 anr,是因為 onCreate 中拋出異常導致后續(xù)代碼無法執(zhí)行,也就是 Activity 生命周期框架代碼無法繼續(xù),同時后續(xù) Message 也無法正常派發(fā),所以界面還沒出來就黑屏了),而 View 點擊事件響應中 crash 可能不會黑屏(也可能會,取決于做什么操作),但是后續(xù) Message 也是無法正常派發(fā)。
拓展環(huán)節(jié)
問:針對上面描述你有什么想法?
答:子線程奔潰沒啥說的,由于主線程發(fā)生了崩潰會導致 Looper 退出,所以我們可以在主線程啟動一個我們自帶 try-catch 的 Looper.loop() 去執(zhí)行主線程任務,相當于這樣我們通過帶 try-catch 的 loop() 替換掉了 ActivityThread main 里面那個 Looper.loop(),這樣就不會出現主線程崩潰后 loop 退出了,也就能繼續(xù)執(zhí)行代碼了,只是當次 crash 的場景可能是無效的,譬如用戶點擊按鈕設置文案 crash 了,點了可能沒反應;同時點擊按鈕啟動的 Activity 的 onCreate 等方法里面有 crash 則會導致黑屏,所以這種 crash 需要區(qū)分對待(譬如上報異常并彈框提醒并直接殺掉進程等)。
下面是核心代碼的簡單實現(Activity 生命周期處理的比較粗略,僅供 demo):
- // Application 啟動就進行替換
- new Handler(getMainLooper()).post(new Runnable() {
- @Override
- public void run() {
- // 每次蹦了就繼續(xù)重新循環(huán),保證永遠都能 loop
- while (true) {
- try {
- Looper.loop();
- } catch (Throwable e) {
- e.printStackTrace();
- // TODO 手動上報錯誤到異常管理平臺,做交互處理等
- if (e.getMessage() != null && e.getMessage().startsWith("Unable to start activity")) {
- // TODO 來自 Activity 生命周期崩潰,殺死進程
- android.os.Process.killProcess(android.os.Process.myPid());
- break;
- }
- }
- }
- }
- });
當然,針對 Activity 生命周期方法內的 crash 黑屏我們除過判斷堆棧日志方式,還能通過 hook ActivityThread 的 mH 主 Handler 實現,將里面的 Message handle 函數托管我們實現,然后進行 try-catch 捕獲,發(fā)現異常就 close 對應 Activity 或者 kill app 即可,這個方案其實網上有現成的開源庫,大家可以去參考下。
本文轉載自微信公眾號「碼農每日一題」,可以通過以下二維碼關注。轉載本文請聯系碼農每日一題公眾號。
網站名稱:Android主線程崩潰與子線程崩潰有什么本質區(qū)別?你是怎么處理的?
路徑分享:http://m.fisionsoft.com.cn/article/coccgjp.html


咨詢
建站咨詢
