姜雨蒙 嚴(yán) 悍
(南京理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院 南京 210094)
?
一種Android運(yùn)行時(shí)異常復(fù)現(xiàn)方法*
姜雨蒙嚴(yán)悍
(南京理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院南京210094)
摘要在Android系統(tǒng)中發(fā)生異常,開發(fā)維護(hù)人員依賴現(xiàn)有的異常記錄難以有效分析導(dǎo)致異常的原因,增加了系統(tǒng)維護(hù)的難度,軟件質(zhì)量難以保障。由于Android平臺(tái)的特點(diǎn),Java的異常處理機(jī)制提供的信息存在不足。針對(duì)傳統(tǒng)日志信息雜亂缺失的問題,給出一個(gè)基于Android系統(tǒng)分層的解決方案,為重異常現(xiàn)提供了一種可行的、具有通用性的解決方法。
關(guān)鍵詞Android; 運(yùn)行時(shí)異常處理; 異常重現(xiàn)
Class NumberTN959.53
1引言
目前移動(dòng)開發(fā)是軟件開發(fā)的主流方式。但由于移動(dòng)手機(jī)的多樣性,用戶操作的復(fù)雜性,移動(dòng)軟件投入使用后發(fā)生異常,開發(fā)人員對(duì)異常發(fā)生的根本原因很難定位。異常會(huì)導(dǎo)致用戶業(yè)務(wù)中斷,用戶輸入數(shù)據(jù)失效,不僅浪費(fèi)用戶處理業(yè)務(wù)時(shí)間,用戶滿意度降低。開發(fā)人員想要快速定位異常,修復(fù)異常并發(fā)布新版本來修復(fù)異常是非常困難的。
傳統(tǒng)Java發(fā)生異常時(shí)能提供一組基礎(chǔ)異常信息(Basic Exception Message,BEM)。BEM通常包含{方法全名,代碼行,異常類型,異常消息及時(shí)間}。其中,方法全名包含方法所在的包、類。通過BEM信息可以得知發(fā)生異常時(shí)代碼行。但導(dǎo)致異常通常是由之前的操作導(dǎo)致的。開發(fā)人員需要重現(xiàn)異常來協(xié)助定位和解決異常。
Android做為目前主流的移動(dòng)手機(jī)操作系統(tǒng),在進(jìn)行Android軟件開發(fā)時(shí)同樣面臨這樣的問題。通過研究一些資料發(fā)現(xiàn),傳統(tǒng)在Android平臺(tái)解決異常的方法是開發(fā)人員自己在程序關(guān)鍵位置做日志記錄[1]。程序會(huì)定時(shí)將所有日志信息傳遞給服務(wù)器。但在移動(dòng)平臺(tái),導(dǎo)致異常的原因一方面是因?yàn)橐苿?dòng)平臺(tái)的硬件環(huán)境復(fù)雜。有些異常只在部分手機(jī)上出現(xiàn),而在別的手機(jī)上表現(xiàn)正常。另一方面日志信息繁雜,對(duì)解決異常問題缺乏系統(tǒng)性描述。有時(shí)候甚至?xí)鸬礁蓴_作用[2]。因此,開發(fā)人員很難利用日志定位在用戶端軟件發(fā)生的異常。
因此,本文研究目的是:在異常發(fā)生后,協(xié)助開發(fā)維護(hù)人員根據(jù)記錄提供的信息重現(xiàn)異常,加快異常定位速度。本文研究出發(fā)點(diǎn)是將異常作為一種“自解釋對(duì)象”,能自我說明導(dǎo)致異常出現(xiàn)的條件,使開發(fā)維護(hù)人員能在特定語境中重現(xiàn)異常,準(zhǔn)確分析其原因,進(jìn)而采取措施來消除異常。
主要針對(duì)Android平臺(tái)會(huì)引起程序崩潰的運(yùn)行時(shí)異常的處理,本文試圖給出一種改進(jìn)Android日志系統(tǒng)的解決方案,使開發(fā)人員在面對(duì)移動(dòng)平臺(tái)定位異常困難的問題時(shí),可以快速重現(xiàn)異常,加快定位速度,提升軟件維護(hù)效率,從而提高軟件的穩(wěn)定性和質(zhì)量。
研究依據(jù)如下: 1) 任何異常都有原因,不存在不能解釋原因的異常。 2) 目前尚沒有某種技術(shù)或方法能有效證明一個(gè)復(fù)雜系統(tǒng)無異常。盡管可捕獲所有異常,但若不從根本上消除,它仍會(huì)再現(xiàn)。 3) 只要有足夠有效的信息,異常原因是可分析的,而且大部分可消除[3]。
2Android程序分層模型
一個(gè)Android程序由數(shù)個(gè)模塊組成,其中用戶能直接感知的主要是Application,Activity和View三個(gè)部分。
2.1Android程序結(jié)構(gòu)
Application是隨著程序啟動(dòng)時(shí)創(chuàng)建的一個(gè)對(duì)象。在Android系統(tǒng)中,一個(gè)進(jìn)程只與一個(gè)Application對(duì)象綁定,也就是說一個(gè)程序的生命周期與自身Application對(duì)象是完全一致的。在一個(gè)Application對(duì)象中,可以實(shí)現(xiàn)多個(gè)Activity對(duì)象[4]。
Activity是單獨(dú)用于處理用戶操作的類,是用戶可視化的執(zhí)行接口。Activity對(duì)象會(huì)在Application中創(chuàng)建,形成程序基礎(chǔ)的可視化界面。用戶行為必須在一個(gè)Activity對(duì)象中執(zhí)行。Activity的生命周期包含七種方法:創(chuàng)建onCreate()、啟動(dòng)onStart()、恢復(fù)onResume()、暫停onPause()、停止onStop()、銷毀onDestory(),重啟onRestart()。由于Android采用IOC(Inversion of Control,控制反轉(zhuǎn))設(shè)計(jì)模式,當(dāng)一個(gè)Activity進(jìn)入某種狀態(tài)時(shí),都會(huì)主動(dòng)按照一定順序調(diào)用這七個(gè)方法[4]。
圖1是Activity的生命周期,其中矩形框表明Activity在狀態(tài)轉(zhuǎn)換之間的回調(diào)操作,開發(fā)人員可重寫實(shí)現(xiàn)以執(zhí)行應(yīng)用相關(guān)代碼。
開發(fā)人員擴(kuò)展Activity基類設(shè)計(jì)自己的子類,作為View控件的容器。
View作為所有控件的總稱,是構(gòu)建用戶界面組件(如Button,TextView等)的基類,可對(duì)用戶交互事件做出響應(yīng)。一個(gè)View占用屏幕上的一個(gè)矩形區(qū)域并負(fù)責(zé)界面繪制和事件處理[5]。

圖1 Activity的生命周期
一個(gè)Android應(yīng)用程序主要分成三個(gè)部分:
1) Application對(duì)象,代表整個(gè)程序的生命周期,是承載Activity的容器;
2) Activity對(duì)象,呈現(xiàn)程序的界面,是承載View的容器;
3) View對(duì)象,響應(yīng)用戶操作的最小單位。
2.2Android程序的簡(jiǎn)化模型
本文研究目的是為了幫助開發(fā)人員重現(xiàn)在用戶手機(jī)上程序發(fā)生的異常。而通常用戶手機(jī)上發(fā)生的異常是由用戶操作引起,而根源在于應(yīng)用程序設(shè)計(jì)不當(dāng)或缺陷造成的。因此從用戶角度,將Android應(yīng)用程序進(jìn)行分層抽象,得到一個(gè)四層結(jié)構(gòu)。不同層次都會(huì)發(fā)生異常。發(fā)生異常的層次越低,重現(xiàn)異常所需開銷越少;層次越高,需要的成本越高。從高到底,這四個(gè)層次依次為
1) 系統(tǒng)層:在應(yīng)用程序所在宿主機(jī),主要包含硬件環(huán)境、系統(tǒng)ROM版本等。
2) 應(yīng)用層:Application對(duì)象。
3) 活動(dòng)層:Activity對(duì)象。
4) 操作層:View對(duì)象,支持用戶交互操作。
2.3Android模型與異常關(guān)系
表1列出不同層次上異常發(fā)生的原因,及還原該異常所需要的代價(jià)。
本文關(guān)注在應(yīng)用層、活動(dòng)層和操作上異常還原,對(duì)于系統(tǒng)層的異常還原并不在本文的討論范圍中。

表1 不同層次的異常原因和還原異常成本
3系統(tǒng)監(jiān)控與異常還原
為了還原異常,需要從兩方面入手: 1) 對(duì)程序正常狀態(tài)下,記錄用戶操作的必要信息。 2) 在發(fā)生異常時(shí)保留異常信息。
3.1模塊設(shè)計(jì)
圖2中,異常處理模塊以上是一個(gè)Android程序正常運(yùn)行部分。監(jiān)控模塊即為本文設(shè)計(jì)的模塊,它可以監(jiān)控Activity行為和View行為。行為記錄會(huì)暫時(shí)存儲(chǔ)在內(nèi)存中。如果沒有發(fā)生異常,這些記錄不會(huì)被保存下來。當(dāng)程序發(fā)生未處理的異常時(shí),異常會(huì)被傳入異常處理模塊中處理。異常處理模塊會(huì)將異常信息存儲(chǔ)在本地磁盤。同時(shí),監(jiān)控的信息也會(huì)一并存入本地文件。

圖2 監(jiān)控系統(tǒng)結(jié)構(gòu)圖
3.2系統(tǒng)監(jiān)控與記錄
本文采用面向方面編程(Aspect-Oriented Programming,AOP)設(shè)計(jì)模式,主要使用語言AspectJ,對(duì)系統(tǒng)信息進(jìn)行監(jiān)控,實(shí)現(xiàn)監(jiān)控代碼對(duì)業(yè)務(wù)代碼的剝離,減少對(duì)業(yè)務(wù)代碼的干擾[7]。
3.2.1應(yīng)用層監(jiān)控
Activity需要記錄的信息主要分為兩部分: 1) 每個(gè)Activity的初始狀態(tài)。 2) Activity的變化過程。
Activity對(duì)象的初始狀態(tài)由自身的onCreate()方法和傳入的數(shù)據(jù)決定[10]。Activity對(duì)象對(duì)另一個(gè)Activity對(duì)象傳入數(shù)據(jù)通常方式是采用Intent類的對(duì)象實(shí)現(xiàn)。因此需要在對(duì)每個(gè)用Intent接收信息的Activity的onCreate()方法中記錄Intent對(duì)象,從而可以還原Activity的初始狀態(tài)。
利用AspectJ監(jiān)聽每個(gè)Activity的onCreate()方法,再用java反射機(jī)制從onCreate()方法中提取Intent對(duì)象。如果onCreate()方法中有使用Intent對(duì)象進(jìn)行傳值,那么將Intent對(duì)象存入一個(gè)HashMap中,key值為Activity的類名,value為由Activity傳入的Intent對(duì)象。
根據(jù)圖1,Activity進(jìn)行狀態(tài)轉(zhuǎn)換時(shí)將會(huì)調(diào)用狀態(tài)同名方法。所有狀態(tài)方法的開頭字母都是“on”,因此通過AspectJ監(jiān)控Activity類中on開頭的方法名,就能實(shí)現(xiàn)對(duì)活動(dòng)層的監(jiān)聽。
在AspectJ中,可以通過定義Pointcut來實(shí)現(xiàn)這個(gè)效果[4]。如:
@Pointcut("execution(* *..DemoActivity.on*(..))")
監(jiān)聽了DemoActivity中所有on開頭的方法名。通過監(jiān)聽狀態(tài)方法的調(diào)用,可以得知活動(dòng)層當(dāng)前狀態(tài)。將當(dāng)前狀態(tài),與Activity類名,時(shí)間戳一起封裝成記錄信息,格式如下:應(yīng)用層記錄結(jié)構(gòu)為:{時(shí)間,Activity類名,狀態(tài)}。
3.2.2活動(dòng)層和操作層監(jiān)控
對(duì)于Android手機(jī)來說,用戶的所有操作都是建立在與Android屏幕交互基礎(chǔ)上,即觸摸屏事件。對(duì)于觸摸屏事件(鼠標(biāo)事件)有按下有:按下、彈起、移動(dòng)、滑動(dòng)、滾動(dòng)。按下、彈起、移動(dòng)(down、move、up)是簡(jiǎn)單的觸摸屏事件,而雙擊、長按、滑動(dòng)、滾動(dòng)需要根據(jù)運(yùn)動(dòng)的軌跡來做識(shí)別的。在Android中有專門的類去識(shí)別,android.view.GestureDetector。
Android的觸摸和手勢(shì)事件的是需要繼承touch接口,重寫里面方法。在這些方法里,Android系統(tǒng)會(huì)上拋被觸發(fā)的view對(duì)象和事件類型。因此,由AspectJ監(jiān)聽這些方法,從而獲知是用戶點(diǎn)擊的view和執(zhí)行的觸屏事件,從而進(jìn)一步得知用戶執(zhí)行的操作指令[5]。
根據(jù)用戶的操作指令已經(jīng)響應(yīng)指令的代碼,從而可以得到一個(gè)操作指令的信息。所以,監(jiān)控操作層執(zhí)行過程只需要記錄用戶的操作指令。記錄結(jié)構(gòu)如下:{時(shí)間,view對(duì)象,觸屏事件類型}。
3.2.3操作流
操作流,即用戶在使用應(yīng)用軟件過程中按照時(shí)間先后順序排列的操作指令。
通過對(duì)應(yīng)用層的監(jiān)控,可以形成一個(gè)粗密度的操作流,即Activity之間相互切換的過程。用戶在每一個(gè)Activity中會(huì)有更加細(xì)密度的操作。用戶細(xì)密度的操作流則被活動(dòng)層和操作層的監(jiān)控記錄下來。如圖3所示。

圖3 操作流分類
通常,不同的Activity中承擔(dān)的是不同的業(yè)務(wù),所完成的功能是不一樣的。因此,在應(yīng)用層的操作流反映出的是程序整體業(yè)務(wù)的變化。活動(dòng)層的操作流更關(guān)注用戶具體的行為,反映出的是用戶具體操作指令。
操作流最終會(huì)被記錄在兩個(gè)ArrayList中。應(yīng)用層信息記錄在應(yīng)用層的ArrayList,活動(dòng)層的操作流記錄在活動(dòng)層的ArrayList中。
3.3異常發(fā)生時(shí)處理
當(dāng)一個(gè)未捕獲的運(yùn)行時(shí)異常發(fā)生時(shí),會(huì)導(dǎo)致發(fā)生異常的活動(dòng)層崩潰。利用前文活動(dòng)層崩潰對(duì)Application層不影響的特點(diǎn)和java中UncaughtExceptionHandler類的性質(zhì),在應(yīng)用層Application中生成一個(gè)ExceptionHandler對(duì)象,它是UncaughtExceptionHandler的子類。當(dāng)異常發(fā)生時(shí)可以接管程序,此時(shí)可以將當(dāng)異常發(fā)生時(shí)的信息,保存下來,避免信息丟失。
此時(shí)通過捕獲異常對(duì)象,生成BEM信息。同時(shí),ExceptionHandler還會(huì)查詢?cè)撥浖蛙浖姹咎?hào)。
ExceptionHandler再把內(nèi)存中ArrayList和HashMap中數(shù)據(jù)一并取出,在手機(jī)本地生成一個(gè)異常日志文件,將這些信息寫入文件內(nèi),文件名用軟件名和軟件版本號(hào)命名。最后退出程序。
當(dāng)程序重新啟動(dòng)時(shí),檢測(cè)該文件是否存在。如果存在,則將該文件上傳至服務(wù)器后,再把文件刪除。
4異常實(shí)例分析
在傳統(tǒng)的Android日志信息中,當(dāng)發(fā)生異常時(shí),日志提供的是以下信息:
12-10 15:32:40.734: FATAL EXCEPTION: main
12-10 15:32:40.734: Process: com.example.androidtestproject, PID: 3816
12-10 15:32:40.734: java.lang.NullPointerException
12-10 15:32:40.734: at com.example.androidtestproject.CounterView.onDraw(CounterView.java:36)
12-10 15:32:40.734: at android.view.View.draw(View.java:14613)
12-10 15:32:40.734: at android.view.View.getDisplayList(View.java:13510)
該信息只指出了異常類型和出錯(cuò)代碼行。由于Android自身機(jī)制原因,剩下的錯(cuò)誤信息都來自Android自身框架代碼。在該例中,出錯(cuò)的類CounterView是一個(gè)自定義View,它在程序中有多個(gè)實(shí)例對(duì)象。由于其中某個(gè)實(shí)例對(duì)象傳入了Null,導(dǎo)致了CounterView類內(nèi)onDraw方法發(fā)生了空指針異常。但從以上信息來看是無法得知具體哪個(gè)對(duì)象導(dǎo)致的該異常。
通過采用本文中的解決方案,根據(jù)應(yīng)用層操作流記錄,可以查看到如下信息:
{ 01-08 00:44:01.214,MainActivity,onCreate方法已執(zhí)行}
{ 01-08 00:44:01.214,MainActivity,onStart方法已執(zhí)行}
{ 01-08 00:44:09.527,otherActivity,onCreate方法已執(zhí)行}
{ 01-08 00:44:09.527, otherActivity, onStart方法已執(zhí)行}
該記錄并沒有顯示全部的狀態(tài)記錄,這是由于此程序中的Activity并沒有重寫全部的狀態(tài)方法導(dǎo)致的。但因?yàn)橐呀?jīng)執(zhí)行了otherActivity中的onCreate方法,故不影響判斷出程序是進(jìn)入了otherActivity后發(fā)生的異常。由于onStart方法已經(jīng)執(zhí)行,因此可以判斷otherActivity已經(jīng)進(jìn)入運(yùn)行階段。
所以取出otherActivity中活動(dòng)層操作流記錄:
{ 01-08 00:44:30.365,Button,onClick }
{ 01-08 00:44:37.125,CounterView,onClick}
這說明是CounterView類的對(duì)象觸發(fā)點(diǎn)擊事件的操作導(dǎo)致的異常。根據(jù)代碼得知,MainActivity并沒有給otherActivity傳值,所以只需要重新啟動(dòng)otherActivity,點(diǎn)擊CounterView類的對(duì)象,異常重現(xiàn)。因此可以得出結(jié)論:導(dǎo)致異常發(fā)生的原因是在操作層中。檢查CounterView類的對(duì)象中onClick方法,排查異常。如果點(diǎn)擊CounterView類的對(duì)象并沒有發(fā)生異常,而點(diǎn)擊Button對(duì)象后再點(diǎn)擊CounterView類的對(duì)象,異常重現(xiàn),則可以判斷異常的原因是在活動(dòng)層中,即Button對(duì)象的行為對(duì)CounterView類的對(duì)象產(chǎn)生了干擾。
本方法在多個(gè)Android軟件中進(jìn)行了實(shí)驗(yàn)。通過收集應(yīng)用層、活動(dòng)層、操作層的信息,獲知了發(fā)生異常前、用戶的操作行為,從而可以在脫離用戶使用環(huán)境還原用戶使用過程,使異常重現(xiàn)。證明了該方法的可行性。
5結(jié)論
本文在分析異常復(fù)雜性原因基礎(chǔ)上,通過對(duì)系統(tǒng)模塊進(jìn)行分層抽象,將系統(tǒng)全局狀態(tài)記錄簡(jiǎn)化為對(duì)具體活動(dòng)層的記錄。通過記錄還原每一層的必要信息,方便開發(fā)人員可以脫離異常發(fā)生的環(huán)境,在開發(fā)環(huán)境中重現(xiàn)異常。
該解決方案可以適用于傳統(tǒng)Android軟件的異常還原。里面主要是利用Android系統(tǒng)運(yùn)行軟件的特點(diǎn),收集信息。因此只要Android應(yīng)用框架行為不發(fā)生改變,本方案可以給大部分Android應(yīng)用程序使用。
然而,在使用過程中也發(fā)現(xiàn)一些不足。由于在Android平臺(tái)軟件存在多樣性,當(dāng)遇到需要頻繁操作的應(yīng)用時(shí),會(huì)觸發(fā)大量觸摸事件,因此會(huì)記錄大量無用信息,反而對(duì)重現(xiàn)異常產(chǎn)生干擾。其次,本方案中未對(duì)程序調(diào)用的傳感器進(jìn)行進(jìn)行監(jiān)控,對(duì)用戶使用傳感器的行為信息缺乏。這可能會(huì)導(dǎo)致部分操作信息丟失。服務(wù)器端獲取的數(shù)據(jù)還過于原始,需要自己翻譯成操作流。在未來的工作中需要在服務(wù)器端實(shí)現(xiàn)異常統(tǒng)計(jì)和異常信息翻譯的工作。
本文提供的模型和方案不同于傳統(tǒng)開發(fā)中在異常發(fā)生現(xiàn)場(chǎng)定位和解決異常。而是利用Android系統(tǒng)的特性,為開發(fā)維護(hù)人員提供一種分層模型的分析方法和一種動(dòng)態(tài)監(jiān)控的方法,提高了異常重現(xiàn)與分析的效率,從而加快開發(fā)速度,提高系統(tǒng)的可靠性和可維護(hù)性,提升用戶滿意度。
參 考 文 獻(xiàn)
[1] 彭智俊,張?jiān)?楊珉.用靜態(tài)信息流分析檢測(cè)Android應(yīng)用中的日志信息[J].小型微型計(jì)算機(jī)系統(tǒng),2013(6):1276-1281.PENG Zhijun, ZHANG Yuan, YANG Min. Static flow analysis detection of Android applications log information[J]. Small and Micro Computer System,2013(6):1276-1281.
[2] Ji C, Chen Z, Xu B, et al. A new mutation analysis method for testing Java exception handling[C]//Computer Software and Applications Conference, 2009. COMPSAC’09. 33rd Annual IEEE International. IEEE,2009(2):556-561.
[3] 嚴(yán)悍,梁君.多角色協(xié)同Web系統(tǒng)中的異常語境分析與重現(xiàn)[D].南京:南京理工大學(xué),2014.YAN Han, LIANG Jun. Exception Context Reproducing and Analyse for Multi-Role Collaborative Web System[D]. Nanjing: Nanjing University of Science and Technology,2014.
[4] Google, Android APIs官方文檔[EB/OL]. http://www.android-doc.com/reference/android/app/Activity.html,2015-12-03.
Google, Android APIs Official documentation[EB/OL]. http://www.android-doc.com/reference/android/app/Activity.html,2015-12-03.
[5] 余煒.Android觸摸事件分發(fā)機(jī)制[EB/OL]. http://hunankeda110.iteye.com/blog/1944311,2013-09-20.
YU Wei. Android touch event distribution mechanisms[EB/OL]. http://hunankeda110.iteye.com/blog/1944311,2013-09-20.
[6] 阿拉神農(nóng).深入理解Android之AOP[EB/OL]. http://blog.csdn.net/innost/article/details/49387395,2015-12-14.
Aladingshennong. In-depth understanding of Android AOP[EB/OL]. http://blog.csdn.net/innost/article/details/49387395,2015-12-14.
[7] Fernando Cejas. Aspect Oriented Programming in Android[EB/OL]. http://fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android/, 2014-08-03.
[8] Rogers R, Lombardo J, Mednieks Z, et al. Android application development: Programming with the Google SDK[M]. O’Reilly Media, Inc.,2009.
[9] Isohara T, Takemori K, Kubota A. Kernel-based behavior analysis for android malware detection[C]//Computational Intelligence and Security (CIS), 2011 Seventh International Conference on. IEEE,2011:1011-1015.
[10] Ji C, Chen Z, Xu B, et al. A new mutation analysis method for testing Java exception handling[C]//Computer Software and Applications Conference, 2009. COMPSAC’09. 33rd Annual IEEE International. IEEE,2009(2):556-561.
收稿日期:2016年1月10日,修回日期:2016年3月1日
作者簡(jiǎn)介:姜雨蒙,男,碩士研究生,研究方向:Android應(yīng)用,敏感語境分析。嚴(yán)悍,男,博士研究生,研究方向:敏捷開發(fā)方法學(xué)。
中圖分類號(hào)TN959.53
DOI:10.3969/j.issn.1672-9722.2016.07.028
Android Runtime Exception Reproduction Method
JIANG YumengYAN Han
(School of Computer Science and Engineering, Nanjing University of Science and Technology, Nanjing210094)
AbstractAbnormal in the Android system, the development and maintenance personnel to rely on the existing abnormal records is difficult to effectively analyze the causes of abnormal, increase the difficulty of system maintenance, software quality is difficult to guarantee. Due to the characteristics of the Android platform, the information provided by the exception handling mechanism of Java is insufficient. Aiming at the problem of traditional log information clutter, a solution based on Android system is presented, which provides a feasible and universal solution for the problem.
Key WordsAndroid, runtime execption handling, exception reoccurs