日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Android主線程崩潰與子線程崩潰有什么本質(zhì)區(qū)別?你是怎么處理的?

問(wèn)答環(huán)節(jié)

晉州網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,晉州網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為晉州上千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的晉州做網(wǎng)站的公司定做!

問(wèn):Android 主線程崩潰與子線程崩潰有什么本質(zhì)區(qū)別?

答:子線程崩潰就是正常的 Java thread 樣子,通過(guò) setDefaultUncaughtExceptionHandler 就能捕獲 ThreadGroup 里對(duì)應(yīng)子線程的異常做后續(xù)處理(啟動(dòng)獨(dú)立進(jìn)程提醒用戶并上報(bào)平臺(tái)等,或者通過(guò)策略下發(fā)忽略特定異常當(dāng)作沒(méi)發(fā)生一樣)。安卓中主線程的 Crash 和子線程 Crash 有一點(diǎn)差異,雖然本質(zhì)都是通過(guò) setDefaultUncaughtExceptionHandler 就能捕獲,但是這背后其實(shí)是有一點(diǎn)竅門(mén)的。由于 Android 主線程啟動(dòng)后通過(guò) MainHandler 的 Looper.loop() 一直保持管道阻塞式的生產(chǎn)消費(fèi)者死循環(huán),所有的主線程代碼都是通過(guò)這個(gè)循環(huán)派發(fā)在 MainLooper 中執(zhí)行的,所以當(dāng)主線程 crash 的場(chǎng)景下,這個(gè)循環(huán)會(huì)被跳出,導(dǎo)致 Looper 無(wú)法再繼續(xù)執(zhí)行其中的其他 Message,所以當(dāng)主線程 crash 時(shí)會(huì)出現(xiàn)幾種不同的表現(xiàn),場(chǎng)景的一種就是在 Activity 的 onCreate 中 crash 會(huì)導(dǎo)致界面黑屏(注意,這種 crash 不是 anr,是因?yàn)?onCreate 中拋出異常導(dǎo)致后續(xù)代碼無(wú)法執(zhí)行,也就是 Activity 生命周期框架代碼無(wú)法繼續(xù),同時(shí)后續(xù) Message 也無(wú)法正常派發(fā),所以界面還沒(méi)出來(lái)就黑屏了),而 View 點(diǎn)擊事件響應(yīng)中 crash 可能不會(huì)黑屏(也可能會(huì),取決于做什么操作),但是后續(xù) Message 也是無(wú)法正常派發(fā)。

拓展環(huán)節(jié)
問(wèn):針對(duì)上面描述你有什么想法?

答:子線程奔潰沒(méi)啥說(shuō)的,由于主線程發(fā)生了崩潰會(huì)導(dǎo)致 Looper 退出,所以我們可以在主線程啟動(dòng)一個(gè)我們自帶 try-catch 的 Looper.loop() 去執(zhí)行主線程任務(wù),相當(dāng)于這樣我們通過(guò)帶 try-catch 的 loop() 替換掉了 ActivityThread main 里面那個(gè) Looper.loop(),這樣就不會(huì)出現(xiàn)主線程崩潰后 loop 退出了,也就能繼續(xù)執(zhí)行代碼了,只是當(dāng)次 crash 的場(chǎng)景可能是無(wú)效的,譬如用戶點(diǎn)擊按鈕設(shè)置文案 crash 了,點(diǎn)了可能沒(méi)反應(yīng);同時(shí)點(diǎn)擊按鈕啟動(dòng)的 Activity 的 onCreate 等方法里面有 crash 則會(huì)導(dǎo)致黑屏,所以這種 crash 需要區(qū)分對(duì)待(譬如上報(bào)異常并彈框提醒并直接殺掉進(jìn)程等)。

下面是核心代碼的簡(jiǎn)單實(shí)現(xiàn)(Activity 生命周期處理的比較粗略,僅供 demo):

 
 
 
 
  1. // Application 啟動(dòng)就進(jìn)行替換
  2. new Handler(getMainLooper()).post(new Runnable() {
  3.     @Override
  4.     public void run() {
  5.         // 每次蹦了就繼續(xù)重新循環(huán),保證永遠(yuǎn)都能 loop
  6.         while (true) {
  7.             try {
  8.                 Looper.loop();
  9.             } catch (Throwable e) {
  10.                 e.printStackTrace();
  11.                 // TODO 手動(dòng)上報(bào)錯(cuò)誤到異常管理平臺(tái),做交互處理等
  12.                 if (e.getMessage() != null && e.getMessage().startsWith("Unable to start activity")) {
  13.                     // TODO 來(lái)自 Activity 生命周期崩潰,殺死進(jìn)程
  14.                     android.os.Process.killProcess(android.os.Process.myPid());
  15.                     break;
  16.                 }
  17.             }
  18.         }
  19.     }
  20. });

當(dāng)然,針對(duì) Activity 生命周期方法內(nèi)的 crash 黑屏我們除過(guò)判斷堆棧日志方式,還能通過(guò) hook ActivityThread 的 mH 主 Handler 實(shí)現(xiàn),將里面的 Message handle 函數(shù)托管我們實(shí)現(xiàn),然后進(jìn)行 try-catch 捕獲,發(fā)現(xiàn)異常就 close 對(duì)應(yīng) Activity 或者 kill app 即可,這個(gè)方案其實(shí)網(wǎng)上有現(xiàn)成的開(kāi)源庫(kù),大家可以去參考下。

本文轉(zhuǎn)載自微信公眾號(hào)「碼農(nóng)每日一題」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼農(nóng)每日一題公眾號(hào)。


本文標(biāo)題:Android主線程崩潰與子線程崩潰有什么本質(zhì)區(qū)別?你是怎么處理的?
文章來(lái)源:http://www.5511xx.com/article/coccgjp.html