国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

一種Android運行時異常復(fù)現(xiàn)方法*

2016-08-10 03:43姜雨蒙
計算機(jī)與數(shù)字工程 2016年7期

姜雨蒙 嚴(yán) 悍

(南京理工大學(xué)計算機(jī)科學(xué)與工程學(xué)院 南京 210094)

?

一種Android運行時異常復(fù)現(xiàn)方法*

姜雨蒙嚴(yán)悍

(南京理工大學(xué)計算機(jī)科學(xué)與工程學(xué)院南京210094)

摘要在Android系統(tǒng)中發(fā)生異常,開發(fā)維護(hù)人員依賴現(xiàn)有的異常記錄難以有效分析導(dǎo)致異常的原因,增加了系統(tǒng)維護(hù)的難度,軟件質(zhì)量難以保障。由于Android平臺的特點,Java的異常處理機(jī)制提供的信息存在不足。針對傳統(tǒng)日志信息雜亂缺失的問題,給出一個基于Android系統(tǒng)分層的解決方案,為重異?,F(xiàn)提供了一種可行的、具有通用性的解決方法。

關(guān)鍵詞Android; 運行時異常處理; 異常重現(xiàn)

Class NumberTN959.53

1引言

目前移動開發(fā)是軟件開發(fā)的主流方式。但由于移動手機(jī)的多樣性,用戶操作的復(fù)雜性,移動軟件投入使用后發(fā)生異常,開發(fā)人員對異常發(fā)生的根本原因很難定位。異常會導(dǎo)致用戶業(yè)務(wù)中斷,用戶輸入數(shù)據(jù)失效,不僅浪費用戶處理業(yè)務(wù)時間,用戶滿意度降低。開發(fā)人員想要快速定位異常,修復(fù)異常并發(fā)布新版本來修復(fù)異常是非常困難的。

傳統(tǒng)Java發(fā)生異常時能提供一組基礎(chǔ)異常信息(Basic Exception Message,BEM)。BEM通常包含{方法全名,代碼行,異常類型,異常消息及時間}。其中,方法全名包含方法所在的包、類。通過BEM信息可以得知發(fā)生異常時代碼行。但導(dǎo)致異常通常是由之前的操作導(dǎo)致的。開發(fā)人員需要重現(xiàn)異常來協(xié)助定位和解決異常。

Android做為目前主流的移動手機(jī)操作系統(tǒng),在進(jìn)行Android軟件開發(fā)時同樣面臨這樣的問題。通過研究一些資料發(fā)現(xiàn),傳統(tǒng)在Android平臺解決異常的方法是開發(fā)人員自己在程序關(guān)鍵位置做日志記錄[1]。程序會定時將所有日志信息傳遞給服務(wù)器。但在移動平臺,導(dǎo)致異常的原因一方面是因為移動平臺的硬件環(huán)境復(fù)雜。有些異常只在部分手機(jī)上出現(xiàn),而在別的手機(jī)上表現(xiàn)正常。另一方面日志信息繁雜,對解決異常問題缺乏系統(tǒng)性描述。有時候甚至?xí)鸬礁蓴_作用[2]。因此,開發(fā)人員很難利用日志定位在用戶端軟件發(fā)生的異常。

因此,本文研究目的是:在異常發(fā)生后,協(xié)助開發(fā)維護(hù)人員根據(jù)記錄提供的信息重現(xiàn)異常,加快異常定位速度。本文研究出發(fā)點是將異常作為一種“自解釋對象”,能自我說明導(dǎo)致異常出現(xiàn)的條件,使開發(fā)維護(hù)人員能在特定語境中重現(xiàn)異常,準(zhǔn)確分析其原因,進(jìn)而采取措施來消除異常。

主要針對Android平臺會引起程序崩潰的運行時異常的處理,本文試圖給出一種改進(jìn)Android日志系統(tǒng)的解決方案,使開發(fā)人員在面對移動平臺定位異常困難的問題時,可以快速重現(xiàn)異常,加快定位速度,提升軟件維護(hù)效率,從而提高軟件的穩(wěn)定性和質(zhì)量。

研究依據(jù)如下: 1) 任何異常都有原因,不存在不能解釋原因的異常。 2) 目前尚沒有某種技術(shù)或方法能有效證明一個復(fù)雜系統(tǒng)無異常。盡管可捕獲所有異常,但若不從根本上消除,它仍會再現(xiàn)。 3) 只要有足夠有效的信息,異常原因是可分析的,而且大部分可消除[3]。

2Android程序分層模型

一個Android程序由數(shù)個模塊組成,其中用戶能直接感知的主要是Application,Activity和View三個部分。

2.1Android程序結(jié)構(gòu)

Application是隨著程序啟動時創(chuàng)建的一個對象。在Android系統(tǒng)中,一個進(jìn)程只與一個Application對象綁定,也就是說一個程序的生命周期與自身Application對象是完全一致的。在一個Application對象中,可以實現(xiàn)多個Activity對象[4]。

Activity是單獨用于處理用戶操作的類,是用戶可視化的執(zhí)行接口。Activity對象會在Application中創(chuàng)建,形成程序基礎(chǔ)的可視化界面。用戶行為必須在一個Activity對象中執(zhí)行。Activity的生命周期包含七種方法:創(chuàng)建onCreate()、啟動onStart()、恢復(fù)onResume()、暫停onPause()、停止onStop()、銷毀onDestory(),重啟onRestart()。由于Android采用IOC(Inversion of Control,控制反轉(zhuǎn))設(shè)計模式,當(dāng)一個Activity進(jìn)入某種狀態(tài)時,都會主動按照一定順序調(diào)用這七個方法[4]。

圖1是Activity的生命周期,其中矩形框表明Activity在狀態(tài)轉(zhuǎn)換之間的回調(diào)操作,開發(fā)人員可重寫實現(xiàn)以執(zhí)行應(yīng)用相關(guān)代碼。

開發(fā)人員擴(kuò)展Activity基類設(shè)計自己的子類,作為View控件的容器。

View作為所有控件的總稱,是構(gòu)建用戶界面組件(如Button,TextView等)的基類,可對用戶交互事件做出響應(yīng)。一個View占用屏幕上的一個矩形區(qū)域并負(fù)責(zé)界面繪制和事件處理[5]。

圖1 Activity的生命周期

一個Android應(yīng)用程序主要分成三個部分:

1) Application對象,代表整個程序的生命周期,是承載Activity的容器;

2) Activity對象,呈現(xiàn)程序的界面,是承載View的容器;

3) View對象,響應(yīng)用戶操作的最小單位。

2.2Android程序的簡化模型

本文研究目的是為了幫助開發(fā)人員重現(xiàn)在用戶手機(jī)上程序發(fā)生的異常。而通常用戶手機(jī)上發(fā)生的異常是由用戶操作引起,而根源在于應(yīng)用程序設(shè)計不當(dāng)或缺陷造成的。因此從用戶角度,將Android應(yīng)用程序進(jìn)行分層抽象,得到一個四層結(jié)構(gòu)。不同層次都會發(fā)生異常。發(fā)生異常的層次越低,重現(xiàn)異常所需開銷越少;層次越高,需要的成本越高。從高到底,這四個層次依次為

1) 系統(tǒng)層:在應(yīng)用程序所在宿主機(jī),主要包含硬件環(huán)境、系統(tǒng)ROM版本等。

2) 應(yīng)用層:Application對象。

3) 活動層:Activity對象。

4) 操作層:View對象,支持用戶交互操作。

2.3Android模型與異常關(guān)系

表1列出不同層次上異常發(fā)生的原因,及還原該異常所需要的代價。

本文關(guān)注在應(yīng)用層、活動層和操作上異常還原,對于系統(tǒng)層的異常還原并不在本文的討論范圍中。

表1 不同層次的異常原因和還原異常成本

3系統(tǒng)監(jiān)控與異常還原

為了還原異常,需要從兩方面入手: 1) 對程序正常狀態(tài)下,記錄用戶操作的必要信息。 2) 在發(fā)生異常時保留異常信息。

3.1模塊設(shè)計

圖2中,異常處理模塊以上是一個Android程序正常運行部分。監(jiān)控模塊即為本文設(shè)計的模塊,它可以監(jiān)控Activity行為和View行為。行為記錄會暫時存儲在內(nèi)存中。如果沒有發(fā)生異常,這些記錄不會被保存下來。當(dāng)程序發(fā)生未處理的異常時,異常會被傳入異常處理模塊中處理。異常處理模塊會將異常信息存儲在本地磁盤。同時,監(jiān)控的信息也會一并存入本地文件。

圖2 監(jiān)控系統(tǒng)結(jié)構(gòu)圖

3.2系統(tǒng)監(jiān)控與記錄

本文采用面向方面編程(Aspect-Oriented Programming,AOP)設(shè)計模式,主要使用語言AspectJ,對系統(tǒng)信息進(jìn)行監(jiān)控,實現(xiàn)監(jiān)控代碼對業(yè)務(wù)代碼的剝離,減少對業(yè)務(wù)代碼的干擾[7]。

3.2.1應(yīng)用層監(jiān)控

Activity需要記錄的信息主要分為兩部分: 1) 每個Activity的初始狀態(tài)。 2) Activity的變化過程。

Activity對象的初始狀態(tài)由自身的onCreate()方法和傳入的數(shù)據(jù)決定[10]。Activity對象對另一個Activity對象傳入數(shù)據(jù)通常方式是采用Intent類的對象實現(xiàn)。因此需要在對每個用Intent接收信息的Activity的onCreate()方法中記錄Intent對象,從而可以還原Activity的初始狀態(tài)。

利用AspectJ監(jiān)聽每個Activity的onCreate()方法,再用java反射機(jī)制從onCreate()方法中提取Intent對象。如果onCreate()方法中有使用Intent對象進(jìn)行傳值,那么將Intent對象存入一個HashMap中,key值為Activity的類名,value為由Activity傳入的Intent對象。

根據(jù)圖1,Activity進(jìn)行狀態(tài)轉(zhuǎn)換時將會調(diào)用狀態(tài)同名方法。所有狀態(tài)方法的開頭字母都是“on”,因此通過AspectJ監(jiān)控Activity類中on開頭的方法名,就能實現(xiàn)對活動層的監(jiān)聽。

在AspectJ中,可以通過定義Pointcut來實現(xiàn)這個效果[4]。如:

@Pointcut("execution(* *..DemoActivity.on*(..))")

監(jiān)聽了DemoActivity中所有on開頭的方法名。通過監(jiān)聽狀態(tài)方法的調(diào)用,可以得知活動層當(dāng)前狀態(tài)。將當(dāng)前狀態(tài),與Activity類名,時間戳一起封裝成記錄信息,格式如下:應(yīng)用層記錄結(jié)構(gòu)為:{時間,Activity類名,狀態(tài)}。

3.2.2活動層和操作層監(jiān)控

對于Android手機(jī)來說,用戶的所有操作都是建立在與Android屏幕交互基礎(chǔ)上,即觸摸屏事件。對于觸摸屏事件(鼠標(biāo)事件)有按下有:按下、彈起、移動、滑動、滾動。按下、彈起、移動(down、move、up)是簡單的觸摸屏事件,而雙擊、長按、滑動、滾動需要根據(jù)運動的軌跡來做識別的。在Android中有專門的類去識別,android.view.GestureDetector。

Android的觸摸和手勢事件的是需要繼承touch接口,重寫里面方法。在這些方法里,Android系統(tǒng)會上拋被觸發(fā)的view對象和事件類型。因此,由AspectJ監(jiān)聽這些方法,從而獲知是用戶點擊的view和執(zhí)行的觸屏事件,從而進(jìn)一步得知用戶執(zhí)行的操作指令[5]。

根據(jù)用戶的操作指令已經(jīng)響應(yīng)指令的代碼,從而可以得到一個操作指令的信息。所以,監(jiān)控操作層執(zhí)行過程只需要記錄用戶的操作指令。記錄結(jié)構(gòu)如下:{時間,view對象,觸屏事件類型}。

3.2.3操作流

操作流,即用戶在使用應(yīng)用軟件過程中按照時間先后順序排列的操作指令。

通過對應(yīng)用層的監(jiān)控,可以形成一個粗密度的操作流,即Activity之間相互切換的過程。用戶在每一個Activity中會有更加細(xì)密度的操作。用戶細(xì)密度的操作流則被活動層和操作層的監(jiān)控記錄下來。如圖3所示。

圖3 操作流分類

通常,不同的Activity中承擔(dān)的是不同的業(yè)務(wù),所完成的功能是不一樣的。因此,在應(yīng)用層的操作流反映出的是程序整體業(yè)務(wù)的變化。活動層的操作流更關(guān)注用戶具體的行為,反映出的是用戶具體操作指令。

操作流最終會被記錄在兩個ArrayList中。應(yīng)用層信息記錄在應(yīng)用層的ArrayList,活動層的操作流記錄在活動層的ArrayList中。

3.3異常發(fā)生時處理

當(dāng)一個未捕獲的運行時異常發(fā)生時,會導(dǎo)致發(fā)生異常的活動層崩潰。利用前文活動層崩潰對Application層不影響的特點和java中UncaughtExceptionHandler類的性質(zhì),在應(yīng)用層Application中生成一個ExceptionHandler對象,它是UncaughtExceptionHandler的子類。當(dāng)異常發(fā)生時可以接管程序,此時可以將當(dāng)異常發(fā)生時的信息,保存下來,避免信息丟失。

此時通過捕獲異常對象,生成BEM信息。同時,ExceptionHandler還會查詢該軟件名和軟件版本號。

ExceptionHandler再把內(nèi)存中ArrayList和HashMap中數(shù)據(jù)一并取出,在手機(jī)本地生成一個異常日志文件,將這些信息寫入文件內(nèi),文件名用軟件名和軟件版本號命名。最后退出程序。

當(dāng)程序重新啟動時,檢測該文件是否存在。如果存在,則將該文件上傳至服務(wù)器后,再把文件刪除。

4異常實例分析

在傳統(tǒng)的Android日志信息中,當(dāng)發(fā)生異常時,日志提供的是以下信息:

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)

該信息只指出了異常類型和出錯代碼行。由于Android自身機(jī)制原因,剩下的錯誤信息都來自Android自身框架代碼。在該例中,出錯的類CounterView是一個自定義View,它在程序中有多個實例對象。由于其中某個實例對象傳入了Null,導(dǎo)致了CounterView類內(nèi)onDraw方法發(fā)生了空指針異常。但從以上信息來看是無法得知具體哪個對象導(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)致的。但因為已經(jīng)執(zhí)行了otherActivity中的onCreate方法,故不影響判斷出程序是進(jìn)入了otherActivity后發(fā)生的異常。由于onStart方法已經(jīng)執(zhí)行,因此可以判斷otherActivity已經(jīng)進(jìn)入運行階段。

所以取出otherActivity中活動層操作流記錄:

{ 01-08 00:44:30.365,Button,onClick }

{ 01-08 00:44:37.125,CounterView,onClick}

這說明是CounterView類的對象觸發(fā)點擊事件的操作導(dǎo)致的異常。根據(jù)代碼得知,MainActivity并沒有給otherActivity傳值,所以只需要重新啟動otherActivity,點擊CounterView類的對象,異常重現(xiàn)。因此可以得出結(jié)論:導(dǎo)致異常發(fā)生的原因是在操作層中。檢查CounterView類的對象中onClick方法,排查異常。如果點擊CounterView類的對象并沒有發(fā)生異常,而點擊Button對象后再點擊CounterView類的對象,異常重現(xiàn),則可以判斷異常的原因是在活動層中,即Button對象的行為對CounterView類的對象產(chǎn)生了干擾。

本方法在多個Android軟件中進(jìn)行了實驗。通過收集應(yīng)用層、活動層、操作層的信息,獲知了發(fā)生異常前、用戶的操作行為,從而可以在脫離用戶使用環(huán)境還原用戶使用過程,使異常重現(xiàn)。證明了該方法的可行性。

5結(jié)論

本文在分析異常復(fù)雜性原因基礎(chǔ)上,通過對系統(tǒng)模塊進(jìn)行分層抽象,將系統(tǒng)全局狀態(tài)記錄簡化為對具體活動層的記錄。通過記錄還原每一層的必要信息,方便開發(fā)人員可以脫離異常發(fā)生的環(huán)境,在開發(fā)環(huán)境中重現(xiàn)異常。

該解決方案可以適用于傳統(tǒng)Android軟件的異常還原。里面主要是利用Android系統(tǒng)運行軟件的特點,收集信息。因此只要Android應(yīng)用框架行為不發(fā)生改變,本方案可以給大部分Android應(yīng)用程序使用。

然而,在使用過程中也發(fā)現(xiàn)一些不足。由于在Android平臺軟件存在多樣性,當(dāng)遇到需要頻繁操作的應(yīng)用時,會觸發(fā)大量觸摸事件,因此會記錄大量無用信息,反而對重現(xiàn)異常產(chǎn)生干擾。其次,本方案中未對程序調(diào)用的傳感器進(jìn)行進(jìn)行監(jiān)控,對用戶使用傳感器的行為信息缺乏。這可能會導(dǎo)致部分操作信息丟失。服務(wù)器端獲取的數(shù)據(jù)還過于原始,需要自己翻譯成操作流。在未來的工作中需要在服務(wù)器端實現(xiàn)異常統(tǒng)計和異常信息翻譯的工作。

本文提供的模型和方案不同于傳統(tǒng)開發(fā)中在異常發(fā)生現(xiàn)場定位和解決異常。而是利用Android系統(tǒng)的特性,為開發(fā)維護(hù)人員提供一種分層模型的分析方法和一種動態(tài)監(jiān)控的方法,提高了異常重現(xiàn)與分析的效率,從而加快開發(fā)速度,提高系統(tǒng)的可靠性和可維護(hù)性,提升用戶滿意度。

參 考 文 獻(xiàn)

[1] 彭智俊,張源,楊珉.用靜態(tài)信息流分析檢測Android應(yīng)用中的日志信息[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日

作者簡介:姜雨蒙,男,碩士研究生,研究方向:Android應(yīng)用,敏感語境分析。嚴(yán)悍,男,博士研究生,研究方向:敏捷開發(fā)方法學(xué)。

中圖分類號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