一. 造成系統(tǒng)崩潰的主要原因
1.未捕獲的異常
java + native
2.ANR
3.WTF(What a Terrible Failure)
一般指系統(tǒng)中自己編碼沒(méi)有按照android要求進(jìn)行(比如native沒(méi)有返回值)
二. 系統(tǒng)崩潰所謂優(yōu)化到底要做什么亏镰?
1.規(guī)避問(wèn)題为黎,優(yōu)化用戶(hù)體驗(yàn)
2.收集信息上傳,便于分析
三. 學(xué)習(xí)思路
1. 系統(tǒng)如何對(duì)于這一類(lèi)問(wèn)題進(jìn)行處理
2.結(jié)合framework認(rèn)知榕酒,給出特殊解決方案
3. 日志信息采集
四. 拋出異常導(dǎo)致崩潰分析
1. main函數(shù)啟用本身作為主線程存在涩堤,需要關(guān)注類(lèi)Thread
2.Thread.dispatchUncaughtException
JVM在處理未經(jīng)捕獲的異常時(shí)眷蜓,會(huì)調(diào)用當(dāng)前dispatchUncaughtException函數(shù)進(jìn)行處理。image.png
如果沒(méi)有設(shè)置uncaughtExceptionHandler胎围,將使用線程所在的線程組來(lái)處理這個(gè)未捕獲異常吁系。線程組ThreadGroup實(shí)現(xiàn)了UncaughtExceptionHandler,所以可以用來(lái)處理未捕獲異常白魂。
image.png
3.ThreadGroup
默認(rèn)情況下汽纤,線程組處理未捕獲異常的邏輯是,首先將異常消息通知給父線程組然后嘗試?yán)靡粋€(gè)默認(rèn)的defaultUncaughtExceptionHandler來(lái)處理異常福荸,如果沒(méi)有默認(rèn)的異常處理器,則將錯(cuò)誤信息輸出到System.errimage.png
4.Thread.setUncaughtExceptionHandler
對(duì)外提供設(shè)置Handler功能image.png
5.思考系統(tǒng)是否會(huì)有地方默認(rèn)給我們?cè)O(shè)置了Handler
6.認(rèn)識(shí)RuntimeInit
a.RuntimeInit運(yùn)行時(shí)初始化進(jìn)程
初始化運(yùn)行的一系列信息,其中包含異常處理
image.png
c.commonInit方法
當(dāng)前線程中設(shè)置了setDefaultUncaughtExceptionHandler其類(lèi)型未KillApplicationHandler
image.png
7.KillApplicationHandler
android內(nèi)部默認(rèn)初始化設(shè)置的主線程異常處理方案image.png
方法總結(jié):
- 調(diào)用當(dāng)前ActivityThread的當(dāng)前線程,直接stopProFling
- 上報(bào)AMS崩潰異常信息
- 在最終的 finally中直接kill掉進(jìn)程且退出當(dāng)前進(jìn)程赞赖。
8.結(jié)論
- JVM通過(guò)調(diào)用dispatchUncaughtException來(lái)進(jìn)行未捕獲異常處理。
- 具體對(duì)應(yīng)的提供處理能力的是UncaughtExceptionHandler這個(gè)類(lèi)冤灾。
- 默認(rèn)ThreadGroup提供日志打印處理前域。
- 但是在進(jìn)程環(huán)境初始化時(shí)RuntimeInit提供殺死進(jìn)程的能力。
- 我們可以編寫(xiě)Handler處理類(lèi)來(lái)進(jìn)行未捕獲異常處理瞳购。
五. AMS如何承接應(yīng)用的異常信息上報(bào)
1.handleApplicationCrash
在KillApplicationHandler類(lèi)中的uncaughtException方法话侄,可以看到ActivityManager.getServie().handleApplicationCrash被調(diào)用image.png
2.handleApplicationCrash
image.png
image.png
如果app為null,processName就設(shè)置為system_server,意思是如果沒(méi)有來(lái)源,默認(rèn)判斷是系統(tǒng)進(jìn)程自己学赛。
3.handleApplicationCrashInner
進(jìn)行系統(tǒng)日志輸出年堆,具體處理在addErrorToDropBoximage.png
4.addErrorToDropBox
無(wú)論是crash,native_crash,ANR或是WTF,最終都是來(lái)到這里盏浇。
六. 對(duì)于native crash系統(tǒng)如何做的處理
native_crash的崩潰處理变丧,是有AMS提供一個(gè)NativeCrashListener線程監(jiān)聽(tīng)對(duì)應(yīng)的文件數(shù)據(jù)
1.起始路徑
SystemServer.run --> startOtherServices --> AMS.startObservingNativeCrashesimage.png
2.NativeCrashListener
image.png
image.png
-
通信機(jī)制建立image.png
File socketFile = new File(DEBUGGERD_SOCKET_PATH);//建立一個(gè)信號(hào)機(jī)制通信點(diǎn)。
UnixSocketAddress socketAddr = UnixSocketAddress.createFileSystem(DEBUGGERD_SOCKET_PATH)绢掰;//建立通信管道 -
接收數(shù)據(jù)image.png
peerFd = Os.accept(serverFd, null);//觸發(fā)異常信息
-
處理數(shù)據(jù)
consumeNativeCrashData(peerFd);
image.png -
封裝數(shù)據(jù)痒蓬,提交AMS處理
將數(shù)據(jù)封裝成字符串提交給NativeCrashReporter處理
image.png
將數(shù)據(jù)封裝后提交AMS處理。其實(shí)都是交給handleApplicationCrashInner函數(shù)滴劲,只不過(guò)類(lèi)型不一樣而已攻晒,也就是最終數(shù)據(jù)都是通過(guò)AMS的addErrorToDropBix函數(shù)進(jìn)行具體處理image.png
七. 系統(tǒng)如何處理ANR異常數(shù)據(jù)
1.AnrHelper.appnotResonding
將對(duì)應(yīng)的數(shù)據(jù)封裝成一個(gè)ANR信息包加入到一個(gè)列表中然后愛(ài)妻一個(gè)線程進(jìn)行具體處理image.png
2.startAnrConsumerIfNeeded
image.png
image.png
image.png
image.png
3.AnrConsumerThread
在當(dāng)前信息包中回調(diào)了AnrRecord.appNotRespondingimage.png
AnrRecord中又會(huì)回調(diào)到ProcressRecord
image.png
4.ProcressRecord.appNotResponding
- 記錄ANR數(shù)據(jù)到SLOG(framework日志體系中)
- 記錄ANR數(shù)據(jù)到LOG(主日志體系中)
- dump具體數(shù)據(jù)到指定文件中
-
調(diào)用AMS.addErrorDropBox上報(bào)信息image.png
八. addErrorToDropBox
總結(jié):不管是crash,native_crash,ANR或是WTF,最終都是來(lái)自AMS.addErrorToDropBox班挖,交由它去處理鲁捏。
1.添加頭信息
image.png
image.png
2.讀取對(duì)應(yīng)異常數(shù)據(jù)并拼裝成字符數(shù)據(jù)
image.png
image.png
3.交給DropBoxManager進(jìn)行錄入
image.png
image.png
image.png
image.png
九. DropBoxManager
文件輸入寫(xiě)入image.png