亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        面向觸控類安卓支持庫的應(yīng)用代碼替換技術(shù)

        2020-11-12 10:38:34沈立煒趙文耘
        計算機應(yīng)用與軟件 2020年11期
        關(guān)鍵詞:特征功能方法

        王 超 沈立煒 趙文耘

        1(復(fù)旦大學軟件學院 上海 201203) 2(復(fù)旦大學計算機科學技術(shù)學院 上海 201203) 3(上海市數(shù)據(jù)科學重點實驗室 上海 201203)

        0 引 言

        屏幕觸摸是移動設(shè)備上最主要的人機交互渠道,它能提供例如下拉刷新、左右滑動等應(yīng)用特性,這些特性豐富了界面的展示效果。為了實現(xiàn)這些特性,安卓應(yīng)用開發(fā)者需要基于最基本的onTouchEvent等事件機制集成應(yīng)用響應(yīng)邏輯,但依舊需要編寫相應(yīng)代碼以識別觸控的事件類型,如手指的下拉、釋放等。

        谷歌從2011年開始提供安卓支持庫來輔助開發(fā)者,這些支持庫對開發(fā)者經(jīng)常需要的功能進行了封裝,其中包括了對特定類型界面觸控事件的封裝,例如SwipRefreshLayout控件集成了下拉刷新的功能、DrawerLayout控件集成了左右滑動的功能。使用這些支持庫不僅提高了開發(fā)者的開發(fā)效率,而且能夠在低版本的安卓平臺上使用高版本的功能。但許多開發(fā)者對安卓支持庫提供的功能缺乏了解,因此將已有代碼替換成支持庫需要花費很多的精力去學習,比如開發(fā)者需要對安卓支持庫中下拉刷新、左右側(cè)滑等控件的代碼結(jié)構(gòu)和實現(xiàn)機制有深入的了解。此外,對于維護采用基本事件處理機制編寫的安卓應(yīng)用程序,沒有相應(yīng)的技術(shù)來提醒安卓應(yīng)用維護者進行支持庫的替換,因此維護人員需要花費額外的精力在應(yīng)用程序的源碼中尋找可替換的功能代碼。

        目前已經(jīng)有的代碼替換工作主要集中在API和Library庫的遷移。例如將項目中涉及的棄用API(Deprecated API) 用新的API進行遷移[1]。再比如隨著軟件系統(tǒng)生命周期的變化,對于系統(tǒng)中已有的依賴庫需要用更相關(guān)的庫來進行遷移[2]。而對于將已有功能代碼替換成安卓支持庫中相應(yīng)控件實現(xiàn)的代碼,目前還沒有很好的方法來支持。

        針對上述目標,本文提出了一種面向安卓觸控類支持庫的應(yīng)用代碼替換技術(shù),其利用android.support.v4.widget支持庫下的觸摸控件并以自動化的方式尋找目標應(yīng)用中的可替換點,最終為應(yīng)用開發(fā)者和維護者生成替換建議。具體而言,本文首先提出用以描述安卓事件回調(diào)方法代碼特征的元模型,以此為基礎(chǔ)將目標代碼特征模型與安卓支持庫各控件的特征模型進行匹配。當匹配的結(jié)果能夠進行替換時,分別從功能的實現(xiàn)代碼、監(jiān)聽器的綁定、layout資源文件這三個方面生成替換建議。實驗結(jié)果表明本文所提技術(shù)能夠為支持庫控件相應(yīng)的,且用基本觸控邏輯來實現(xiàn)的事件回調(diào)方法及其資源布局給出正確的替換建議。安卓開發(fā)者利用本文方法,可以分析出應(yīng)用程序中的哪些代碼可以進行替換,以及用安卓支持庫中的哪一個觸摸控件進行替換。

        1 相關(guān)工作

        與本文相關(guān)的研究工作主要包括安卓應(yīng)用分析、代碼相似度檢測、代碼遷移技術(shù)這三個方面。

        安卓應(yīng)用分析方法主要分為動態(tài)分析和靜態(tài)分析兩大類。動態(tài)分析是指當應(yīng)用程序在運行時對應(yīng)用程序的各種行為進行分析,以獲取程序的動態(tài)行為特征。靜態(tài)分析則是分析應(yīng)用程序的源碼或者字節(jié)碼,構(gòu)造應(yīng)用程序的整體結(jié)構(gòu)。對于安卓靜態(tài)分析,目前一些研究工具利用不同類型的圖來描繪程序的特征,如控制流圖、數(shù)據(jù)流圖等[3-4]。為了獲取安卓應(yīng)用程序的源碼或字節(jié)碼,需要對APK安裝包反編譯,常用的反編譯工具有Dexpler[5]、Smail[6]和AndroGuard[7]。本文方法也依賴于安卓靜態(tài)分析技術(shù),在安卓應(yīng)用程序的源碼層面上利用抽象語法樹分析結(jié)果來進一步描繪程序的特征。

        針對代碼的相似問題目前已有很多分析方法,如基于文本識別、基于度量值、基于代碼結(jié)構(gòu)和基于圖結(jié)構(gòu)的代碼相似分析。基于文本識別的代碼相似分析方法是將代碼表示成文本或token序列的方式,進而采用模式匹配技術(shù)來檢測代碼間是否相似。代碼克隆[8]就是基于文本識別的方法來檢測待分析代碼中的重復(fù)部分?;诙攘恐档拇a相似分析方法,不直接比較程序代碼,而是提取選定的度量值信息,形成一組包含這些信息的特征向量,通過比較這些特征向量來比較代碼的相似程度[9]。衡量代碼的度量值有很多,如圈復(fù)雜度、類耦合度和繼承深度等。基于代碼結(jié)構(gòu)的代碼相似分析方法是將待分析的代碼轉(zhuǎn)化成抽象語法樹,進而在語法樹上使用匹配或搜索技術(shù)尋找相似的子樹[10-11]?;趫D結(jié)構(gòu)的代碼相似分析是將程序代碼表示成程序依賴圖來進行分析[12-13]。從兩個特定的起始點開始,尋找兩幅圖中的最大相似子圖。本文方法也利用了基于代碼結(jié)構(gòu)相似的分析方法,將安卓應(yīng)用程序代碼構(gòu)造成抽象語法樹,進而在抽象語法樹的基礎(chǔ)上利用樹匹配算法進行相似分析。

        代碼遷移目前主要分為API遷移和Library庫的遷移。對于API的遷移,可以通過比較兩個版本API在庫中的聲明變化以及兩個版本API在代碼中的使用方式來進行遷移[14]。對于Library庫的遷移,通過對大量開源軟件項目的分析來識別相似庫之間的遷移變化,進而根據(jù)大量的分析數(shù)據(jù)來為Library庫的遷移提供建議[2]。與上述工作不同,本文方法關(guān)注控件支持庫層面的遷移,涉及一組代碼語句與控制結(jié)構(gòu),其中的核心要素是識別目標代碼與安卓支持庫中特定控件在功能和結(jié)構(gòu)上的相似性。

        2 動機案例

        圖1為開發(fā)者使用基礎(chǔ)回調(diào)方法onTouch實現(xiàn)的下拉刷新功能:當手指下拉并松開后,在屏幕上發(fā)送一條通知。該代碼在基礎(chǔ)回調(diào)方法的UP分支下實現(xiàn)發(fā)送通知的業(yè)務(wù)邏輯。

        圖1 下拉刷新案例功能代碼

        圖2為該應(yīng)用程序相應(yīng)的資源文件,其中子視圖由兩個文本框TextView構(gòu)成,這兩個文本框在LinearLayout布局的內(nèi)部。

        圖2 下拉刷新案例資源文件

        圖1的功能代碼和圖2的資源文件都可以用安卓支持庫中已經(jīng)封裝好的控件進行替換。當安卓應(yīng)用軟件開發(fā)者需要用安卓支持庫中已有的控件進行替換時,先要判斷是否能夠替換以及用什么控件進行替換,然后還要分別從功能代碼和資源文件兩塊進行替換。

        對于開發(fā)者來說這將會面臨很多困難。首先許多安卓開發(fā)者對安卓支持庫下提供的功能并不了解,因此將已有代碼替換成支持庫需要一定的學習代價。雖然擁有了一定的安卓支持庫的儲備知識,但沒有相應(yīng)的技術(shù)提醒開發(fā)者該應(yīng)用程序中的某些功能能夠用安卓支持庫中的控件進行替換。此外,一些開發(fā)者知道該項目的有些功能可以使用支持庫的控件進行替換,但是他們不知道如何在項目中進行替換。

        當開發(fā)者使用基于本文方法所開發(fā)的工具時,就可以根據(jù)工具生成的建議快速地在項目中進行支持庫的替換。該工具將會從功能實現(xiàn)代碼、監(jiān)聽器的綁定和布局文件這三個方面給出替換建議。

        圖3為根據(jù)替換建議用SwipeRefreshLayout這個支持庫控件進行替換后的功能代碼。該代碼中,遷移的代碼被放置在SwipeRefreshLayout的onRefresh回調(diào)方法中,同時為SwipeRefreshLayout綁定OnRefresh-Listener監(jiān)聽器,用來監(jiān)聽事件。

        圖3 用支持庫控件替換后的功能代碼

        資源文件的替換如圖4所示。根據(jù)替換建議,使用SwipeRefreshLayout控件節(jié)點來替換原先的LinearLayout節(jié)點。

        圖4 用支持庫替換后的資源文件

        3 支持庫代碼特征模型及其構(gòu)造

        3.1 安卓事件回調(diào)方法的代碼特征元模型

        圖5所示的元模型用來描繪安卓事件回調(diào)方法的代碼特征信息。該元模型既可以表示支持庫中的回調(diào)方法,又可以用來描述目標替換代碼的方法代碼結(jié)構(gòu)。

        圖5 安卓事件回調(diào)方法的代碼特征元模型

        Widget表示安卓支持庫中的一個觸摸控件,在該元模型中,控件包含了一組監(jiān)聽器。每一個監(jiān)聽器負責監(jiān)聽一個或多個事件并觸發(fā)相應(yīng)的回調(diào)方法(Callback)。我們使用一棵特征樹(FeatureTree)來表示Callback的具體代碼及其應(yīng)用邏輯,并以FeatureTreeRoot來表示該特征樹的根節(jié)點。根節(jié)點一般命名為基礎(chǔ)回調(diào)的方法名,例如onTouch、onTouchEvent等。

        特征樹是由一系列表示代碼元素的節(jié)點構(gòu)成,即CodeElement。節(jié)點之間存在Order信息與Include關(guān)系。Order關(guān)系表示同層次代碼元素與同層次代碼元素之間的次序關(guān)系,Include關(guān)系表示外部代碼元素與內(nèi)部代碼元素之間的包含關(guān)系。另外,每一個節(jié)點包含KeyWordSet屬性,用以代表代碼元素中的關(guān)鍵字集合。該集合可包括方法名以及部分靜態(tài)常量名。這些關(guān)鍵字從SDK中提取得來,用以反映代碼的實現(xiàn)功能。

        元模型中列舉了三種特定類型的代碼元素,即代碼控制結(jié)構(gòu)(ControlStructure)、代碼語句(Statement)和插樁點(Instrumentation)。

        ControlStructure用來描述代碼的骨架結(jié)構(gòu),表示程序執(zhí)行的動作順序。本文將控制結(jié)構(gòu)分成兩類,循環(huán)結(jié)構(gòu)(Loop)和分支結(jié)構(gòu)(Branch)。循環(huán)結(jié)構(gòu)包括For、While、Do等,分支結(jié)構(gòu)包括If、Switch等。

        Statement用來記錄代碼結(jié)構(gòu)中的基本語句信息,例如方法調(diào)用信息,Statement就記錄了該方法調(diào)用是在代碼控制結(jié)構(gòu)中的哪個分支下進行調(diào)用的。

        Instrumentation記錄控件回調(diào)方法在代碼中的哪個位置被間接觸發(fā)。例如SwipeRefreshLayout控件中的onRefresh回調(diào)方法是在onTouchEvent這個基礎(chǔ)回調(diào)方法中的UP分支下被間接觸發(fā)的。在進行代碼替換時,用戶實現(xiàn)業(yè)務(wù)功能的代碼就放在該插樁點所記錄的回調(diào)方法的內(nèi)部。

        3.2 目標代碼特征模型的構(gòu)造方法

        算法1是目標代碼特征模型的構(gòu)造方法。該算法的輸入是一個Callback方法,對Callback方法中的每一個結(jié)構(gòu)塊進行迭代分析。算法的輸出是FeatureTree,即一個以樹狀結(jié)構(gòu)表示回調(diào)方法的特征模型。

        算法1目標代碼特征模型的構(gòu)造方法

        Function: BuildFeatureTree

        輸入: Callback。

        輸出: FeatureTree。

        begin

        For each ControlBlock in Callback

        begin

        CNode=CreateNode(Loop/Branch)

        CreateOrder(PreCNode, CNode)

        SNode=CreateNode(Condition)

        AddIncludeNode(CNode, SNode)

        BNode=CreateNode(Statement)

        AddIncludeNode(SNode, BNode)

        PreCNode=CNode

        end

        return FeatureTree

        end

        在迭代過程中,對于每一個結(jié)構(gòu)塊,創(chuàng)建一個ControlStructure類型的節(jié)點,節(jié)點記錄該控制結(jié)構(gòu)的類型是Loop還是Branch,并將此控制結(jié)構(gòu)節(jié)點與父控制結(jié)構(gòu)節(jié)點關(guān)聯(lián)起來。為了記錄控制結(jié)構(gòu)之間的Order關(guān)系,在關(guān)聯(lián)兩個控制結(jié)構(gòu)節(jié)點時以O(shè)rder屬性的邊來連接這兩個節(jié)點??刂平Y(jié)構(gòu)中的條件信息,用Statement類型的節(jié)點來保存,并將該節(jié)點以Include關(guān)系關(guān)聯(lián)到所屬的控制結(jié)構(gòu)節(jié)點上。對于某一個條件下的代碼語句,仍然用Statement類型節(jié)點來保存,并將該節(jié)點以Include關(guān)系關(guān)聯(lián)到所對應(yīng)的分支條件節(jié)點上。如果該控制結(jié)構(gòu)是分支結(jié)構(gòu),則需要對分支結(jié)構(gòu)下的每一個分支條件進行分析。

        3.3 支持庫控件的特征模型構(gòu)建

        首先需要為支持庫每一個觸摸控件中每一個監(jiān)聽器下的每一個回調(diào)方法構(gòu)造特征模型。為了獲取支持庫控件中的回調(diào)方法,可以通過參閱文檔或檢索支持庫中具有Listener的類來找到相應(yīng)的回調(diào)方法。為了找到觸發(fā)回調(diào)方法的調(diào)用語句,需要對回調(diào)方法進行回溯,由于回調(diào)方法有時候并不能在某一個方法中找到對其的調(diào)用,因此回溯過程將分為以下兩種情形:

        (1) 如果在某一個方法中找到觸發(fā)該回調(diào)方法的調(diào)用語句,則以該方法繼續(xù)向上回溯。

        (2) 如果沒有找到觸發(fā)該回調(diào)方法的調(diào)用語句,則利用事先對安卓內(nèi)部回調(diào)方法的總結(jié),找到觸發(fā)該回調(diào)方法的方法,然后以該方法繼續(xù)向上回溯。

        算法2描述了回調(diào)函數(shù)調(diào)用鏈的回溯過程,該算法的輸入是一個支持庫控件中的回調(diào)方法,輸出是控件中的基礎(chǔ)回調(diào)方法。通過算法2,可以將控件中以回調(diào)方法為終點,以基礎(chǔ)回調(diào)方法為起點的方法調(diào)用鏈構(gòu)建完成。接著采用算法1,對基礎(chǔ)回調(diào)方法進行特征模型樹的構(gòu)造。此時的特征模型樹需要加上插樁類型節(jié)點,該節(jié)點存儲了控件中的某個回調(diào)方法,并且將該節(jié)點連接到基礎(chǔ)回調(diào)方法對應(yīng)的代碼塊下。

        算法2回調(diào)函數(shù)調(diào)用鏈的回溯算法

        Function: SearchBaseMethod

        輸入: Callback。

        輸出: BaseMethod。

        begin

        if Callback是基礎(chǔ)回調(diào)方法 then

        begin

        BaseMethod=Caller

        return BaseMethod

        end

        if 找到該回調(diào)方法的Caller then

        begin

        SearchBaseMethod(Caller)

        end

        else then

        begin

        通過整理的回調(diào)方法總結(jié)中找到Caller

        SearchBaseMethod(Caller)

        end

        end

        圖6給出了一個控件特征模型的例子。onTouchEvent是SwipeRefreshLayout控件內(nèi)部的一個基礎(chǔ)回調(diào)函數(shù)。

        圖6 特征模型樹示例

        可以看出,其內(nèi)部是一個分支類型的控制結(jié)構(gòu),用ControlStructure類型的節(jié)點來表示,節(jié)點存儲了該控制結(jié)構(gòu)類型為Branch類型。該結(jié)構(gòu)有三個分支,分別用三個Statement類型的節(jié)點保存分支條件的信息。每一個分支條件下用Statement類型節(jié)點保存該分支下的代碼語句片段信息。由于UP分支下間接調(diào)用了onRefresh這個回調(diào)方法,因此用一個插樁類型的節(jié)點來存儲該回調(diào)方法信息。

        4 目標應(yīng)用的支持庫控件替換

        4.1 代碼替換技術(shù)的方法流程

        代碼替換技術(shù)的方法流程如圖7所示,該方法流程主要分成兩個階段,第一階段是安卓支持庫特征模型的準備,第二階段是基于第一階段支持庫特征模型的代碼替換技術(shù)。

        圖7 代碼替換技術(shù)的方法流程

        安卓支持庫特征模型的準備分成兩個部分:一是回調(diào)方法調(diào)用鏈的構(gòu)建,二是回調(diào)方法特征模型的構(gòu)建?;卣{(diào)方法調(diào)用鏈的構(gòu)建是對于安卓支持庫控件中的每一個回調(diào)方法,找到該方法是在哪個基礎(chǔ)回調(diào)方法中被觸發(fā)的?;卣{(diào)方法特征模型的構(gòu)建是對控件中的每一個回調(diào)方法構(gòu)建特征模型樹。

        支持庫特征模型的代碼替換分成三個部分,分別是基于支持庫特征模型的待替換代碼的定位、匹配和替換。首先需要對待分析的安卓應(yīng)用進行掃描,對應(yīng)用中每一個Activity中的每一個回調(diào)方法進行定位。如果該回調(diào)方法名與支持庫特征模型中的某個基礎(chǔ)回調(diào)方法名一致,則該回調(diào)方法是一個潛在待替換代碼。如果方法名不一致,則繼續(xù)定位應(yīng)用中的下一個回調(diào)方法。對于定位到的一個潛在待替換代碼,采用樹匹配的算法將潛在待替換代碼特征模型樹與控件中相對應(yīng)的特征模型樹進行匹配,根據(jù)匹配結(jié)果判斷能否進行替換。當可以替換時,生成相應(yīng)的替換建議。

        4.2 基于支持庫特征模型的代碼匹配

        為了對目標代碼特征模型樹和安卓支持庫控件的特征模型樹進行匹配比較,本文采用一種樹匹配算法(TM)來尋找兩棵特征模型樹間的最大匹配。S(SA,S1,S2,…,Si)和T(TB、T1,T2,…,Tj)分別是目標代碼特征模型樹和安卓支持庫控件特征模型樹。其中:Si為樹S的第一層子樹的第i個節(jié)點;Tj為樹T的第一層子樹的第j個節(jié)點;SA和SB分別為樹的根節(jié)點。M為兩個特征模型樹的匹配,最大匹配M就是擁有最多節(jié)點對間的匹配,其最大匹配節(jié)點個數(shù)為M+1,加1是因為根節(jié)點也是匹配的節(jié)點對。為了求出M()的最大匹配,采用動態(tài)規(guī)劃的思想,有以下幾種情形:

        1) 當兩個子樹中有一個為空是,匹配數(shù)M為0。

        2) 當兩個子樹都不為空時,可分為以下幾個情形:

        (1) 匹配Si和Tj,這時M(,)變?yōu)镸(,)+W(Si、Tj);

        (2) 匹配Si,這時M()變?yōu)镸();

        (3) 匹配Tj,這時M(,)變?yōu)镸(,)。

        最后根據(jù)樹匹配算法的結(jié)果,計算出兩個特征模型之間的相似度:

        式中:Node(S)和Node(T)分別表示樹S和樹T節(jié)點的個數(shù);TM(S,T)表示通過樹匹配算法計算后返回的兩棵樹間的最大匹配的節(jié)點個數(shù)。

        圖8所示為兩個特征模型樹S和T,節(jié)點中的標號表示該節(jié)點的類型,具有相同標號的節(jié)點看成是相同節(jié)點。利用TM算法可以求出S和T之間的最大匹配為9,因此它們之間的相似度為0.9。

        圖8 兩棵特征模型樹

        因此兩棵特征模型樹的最大匹配節(jié)點個數(shù)越多,則兩棵樹的相似度就越大,也就越相似。對于本文的場景,需要在目標代碼的特征模型樹中匹配到一棵子樹,該子樹即控件基礎(chǔ)回調(diào)方法的特征模型樹。所以最大匹配樹TM(S,T)滿足以下關(guān)系時,目標代碼可以用安卓支持庫里的控件進行替換:

        TM(S,T)=Node(T)

        式中:T表示的是安卓支持庫控件代碼的特征模型樹;S表示的是目標代碼的特征模型樹;Node(T)表示樹T節(jié)點的個數(shù);TM(S,T)表示通過樹匹配算法計算后返回的兩棵樹間的最大匹配的節(jié)點個數(shù)。

        4.3 基于支持庫特征模型的替換

        1) 功能實現(xiàn)代碼和監(jiān)聽器的替換。算法3描述了功能實現(xiàn)代碼和監(jiān)聽器的替換方法。該算法的輸入是兩個特征模型樹,分別是目標代碼的特征模型樹CallbackFeatureTree和能夠用來替換該目標代碼的支持庫控件中的基礎(chǔ)回調(diào)方法的特征模型樹BaseMethodFeatureTree。該算法用CodeSegmentMap來保存能夠被遷移的代碼片段,用NotReplaceSet來保存未被遷移的代碼片段。

        算法3功能實現(xiàn)代碼和監(jiān)聽器的替換算法

        Function: CallbackReplace

        輸入: CallbackFeatureTree, BaseMethodFeatureTree。

        輸出: CodeSegmentMap, NotReplaceCodeSet。

        begin

        for each Statement in CallbackFeatureTree

        begin

        if Statement 對應(yīng)到BaseMethodFeatureTree中的一個插樁點 then

        begin

        for each widget in WidgetSet

        begin

        for each FeatureTreeRoot in widget

        begin

        if FeatureTreeRoot==BaseMethodFeatureTree.root then

        begin

        find Listener where Listener.contain(FeatureTreeRoot)

        CodeSegmentMap.put(控件+監(jiān)聽器+插樁點, Statement)

        end

        end

        end

        end

        if Statement 對應(yīng)不到BaseMethodFeatureTree中的一個節(jié)點 then

        begin

        NotRepalceCodeSet.put(Statement)

        end

        end

        return CodeSegmentMap, NotReplaceCodeSet

        end

        在算法3中,以CallbackFeatureTree為基準,遍歷該特征模型樹上的Statement類型節(jié)點,如果該節(jié)點直接對應(yīng)到BaseMethodFeatureTree中的一個非插樁節(jié)點,那么說明新控件已經(jīng)包含這些語句。如果對應(yīng)的是一個插樁類型的節(jié)點,說明該代碼語句是可以進行遷移的。如果沒有對應(yīng)到任何一個節(jié)點,則將該代碼語句記錄到NotReplaceCodeSet中,該代碼語句無法被遷移。對于監(jiān)聽器的搜索,首先找到BaseMethodFeatureTree是在哪個widget下的,然后在該Widget下找到哪一個listener的孩子節(jié)點中有一個孩子節(jié)點是該BaseMethod的,則該listener就是需要用來替換的監(jiān)聽器。最后以插樁點、監(jiān)聽器和該控件作為key鍵,Statement作為值,記錄到CodeSegmentMap中。

        2) layout資源文件的替換。layout資源文件的替換分成兩步:第一步需要找到待替換的控件是什么;第二步需要找到資源文件是哪一個。在Callback所處的Activity中,可以找到該回調(diào)的監(jiān)聽器,然后向上回溯找到是哪一個對象set了這個監(jiān)聽器,則該對象就是需要找的待替換控件。一個Activity的資源文件是在該Activity中的onCreate方法內(nèi)部的setContentView方法中被加載的,該方法中的參數(shù)就是layout資源文件的名字。例如方法參數(shù)是R.layout.activity_main,則需要的資源文件名稱就是activity_main.xml。

        接著需要在該資源文件中搜索到用戶控件的節(jié)點,當找到該節(jié)點后,將該節(jié)點用支持庫控件進行替換。算法4描述了節(jié)點搜索的方法。

        算法4搜索節(jié)點的算法

        Function: depthSearch

        輸入: root//xml文件的根節(jié)點。

        輸出: child//待替換的控件節(jié)點。

        begin

        nodeStack.add(root)

        while(!node.isEmpty)

        begin

        node=nodeStack.pop()

        list=node.getChildren()

        for child ∈ list

        begin

        nodeStack.add(child)

        if child.name==layout.name then

        begin

        return child

        end

        end

        end

        end

        算法4的實質(zhì)是樹的深度優(yōu)先搜索算法,由于Activity是由一組ViewGroup組成,所以從根節(jié)點出發(fā),依次遍歷每一組ViewGroup。對于每一組ViewGroup,依次搜索其每一個孩子節(jié)點分支,然后再以該孩子節(jié)點為起點,照此方法直到搜索到某一分支的葉子節(jié)點時返回上一層繼續(xù)搜索。當搜索到節(jié)點的名字屬性與待替換控件的名字屬性一致時就停止搜索,那么該位置的節(jié)點就是需要用新的控件去替換的位置。

        4.4 替換建議的生成

        本文給用戶提供的生成建議包含以下幾個部分:

        1) 對于安卓應(yīng)用中可以進行遷移的代碼,需要將支持庫控件、監(jiān)聽器、回調(diào)方法、可遷移代碼組合成完整的代碼片段。為了方便用戶的理解,該建議還增加了一些文字描述,將這些描述與組合后的代碼片段作為完整的可遷移代碼的替換建議。圖9給出了可遷移代碼建議的模板。

        圖9 可遷移代碼的建議模板

        在替換建議中,圖9模板先給出了替換前的代碼,并用文字指明了該代碼片段位于哪個Activity的哪個基礎(chǔ)回調(diào)方法,然后給出了遷移后的代碼示例,也用文字介紹了使用安卓支持庫中的哪個控件進行替換,以及綁定的監(jiān)聽器和回調(diào)方法的信息。

        2) 對于安卓應(yīng)用中未被遷移的代碼,本文同樣將未被遷移代碼和一些文字描述作為替換建議展示給用戶。圖10給出了未被遷移代碼建議的模板,其既給出了未被遷移的代碼片段,又給出了該代碼片段是位于該應(yīng)用中的哪個Activity里的哪個基礎(chǔ)回調(diào)方法下的。

        圖10 未被遷移代碼的建議模板

        3) 對于資源文件的替換,本文依舊給出原資源文件和替換后的資源文件,同時也通過文字描述進行解釋,方便用戶的定位和替換。圖11給出了資源文件替換建議的模板,文字描述告訴用戶資源文件的名稱,以及是用支持庫中的哪個控件進行替換。

        圖11 資源文件替換的建議模板

        5 實驗分析

        圖12為基于本文方法所設(shè)計的工具界面,該工具的界面分成上下兩個部分。上半部分是用戶的輸入部分,用戶需要提供待分析的安卓項目的地址。下半部分是替換建議生成部分,分別從可遷移代碼、資源文件替換和未被遷移代碼三個方面給出替換建議。界面中的三個文本框分別用來展示這三個方面的替換信息。

        圖12 工具界面

        本文主要通過兩組實驗來對本文方法在實際開發(fā)中的實用性進行分析,這兩組實驗分別是針對用戶開發(fā)應(yīng)用的支持庫替換實驗和針對開源應(yīng)用的支持庫替換實驗。

        1) 針對用戶開發(fā)應(yīng)用的支持庫替換實驗。本實驗邀請了三位具有初級安卓開發(fā)經(jīng)驗的同學,讓這三位同學基于基礎(chǔ)回調(diào)方法實現(xiàn)例如下拉操作、側(cè)滑操作等功能的安卓應(yīng)用程序。表1列舉了給這三位同學安排的開發(fā)任務(wù)和提供的開發(fā)建議。

        表1 實驗的開發(fā)任務(wù)與開發(fā)建議

        當三位同學完成應(yīng)用開發(fā)后,利用本文方法對這三個應(yīng)用進行替換分析。最終的分析結(jié)果如表2所示。

        表2 實驗結(jié)果

        其中有兩個應(yīng)用有替換建議,有一個應(yīng)用沒有替換建議。本節(jié)將選取實驗1和實驗3,即一個有替換建議的例子和一個沒有替換建議的例子來對該實驗進行分析。

        (1) 有替換建議的例子分析。該例子用onTouchEvent這個基礎(chǔ)回調(diào)方法實現(xiàn)下拉刷新的功能。圖13是該功能實現(xiàn)代碼的片段。該例子在onTouchEvent的Up分支下寫了一段更新子視圖的邏輯,該邏輯是當手指下拉松開后,在子視圖的ListView中添加一行List。

        圖13 功能實現(xiàn)代碼片段

        通過本文方法分析后,安卓支持庫里的下拉刷新控件SwipeRefreshLayout可以對例子中用基礎(chǔ)回調(diào)方法onTouchEvent實現(xiàn)的下拉刷新代碼進行替換。圖14是可遷移代碼的替換建議,可待遷移代碼放置在SwipeRefreshLayout的onRefresh回調(diào)方法中,該回調(diào)方法是在手指下拉手松后被間接觸發(fā)的。同時為Swipe-RefreshLayout綁定一個setOnRefreshListener監(jiān)聽器,用來監(jiān)聽事件。

        圖14 可遷移代碼的替換建議

        該例子的資源文件如圖15中替換前的代碼所示,該資源文件有兩個視圖,分別是子視圖ListView和父視圖LinearLayout,子視圖ListView在父視圖LinearLayout的內(nèi)部。對于替換后的資源文件如圖15中替換后的代碼所示, ListView這個子視圖在SwipeRefreshLayout控件節(jié)點的內(nèi)部。

        圖15 資源文件的替換建議

        (2) 無替換建議的例子分析。該例子沒有替換建議是因為該例子將下拉刷新的邏輯用一個類封裝好,所以在Activity中只保留了更新子視圖的邏輯,對于下拉刷新的邏輯則在那個類中進行實現(xiàn)。圖16展示了Activity中處理業(yè)務(wù)邏輯的代碼片段。PullRefreshLayout是封裝好的類,在Activity中直接創(chuàng)建該類的一個對象,然后綁定相應(yīng)的監(jiān)聽器來監(jiān)聽動作,在該例子中使用的是setRefreshListener。

        圖16 無替換建議的實現(xiàn)代碼

        2) 針對開源應(yīng)用的支持庫替換實驗。本部分實驗從開源社區(qū)上找了五個與安卓支持庫觸摸控件功能相似的開源安卓應(yīng)用項目,然后利用本文的方法對這五個安卓應(yīng)用項目進行替換分析。本實驗所選取的開源應(yīng)用的來源信息如表3所示,最終分析結(jié)果如表4所示。

        表3 開源項目來源

        表4 開源項目實驗結(jié)果

        可以看出,這五個案例中有2個案例有替換建議輸出,有3個案例沒有替換建議輸出。其中能夠進行替換的項目均包含與支持庫控件相應(yīng)的,且用基本觸控邏輯來實現(xiàn)的事件回調(diào)方法。相對地,在三個沒有替換建議輸出的應(yīng)用中,有一個是使用了封裝好的功能類來實現(xiàn)對應(yīng)的功能,有兩個是直接使用了安卓支持庫中的控件。對于將功能封裝成一個類的情形,本文給出的方法同樣也可以進行分析替換,但這樣做的意義不大。由于用戶已經(jīng)將一個功能封裝好了,那就沒有必要再去用安卓支持庫里的控件進行替換,因此本文設(shè)計的方法對封裝好的功能類是不進行分析的。

        6 結(jié) 語

        本文提出了一種面向安卓觸控類支持庫的應(yīng)用代碼替換技術(shù)。首先設(shè)計了一種用于描述安卓事件回調(diào)方法中代碼特征的元模型,其不僅能夠表示支持庫中的回調(diào)函數(shù),也可以用來描述目標替換代碼中的方法代碼結(jié)構(gòu);接著基于安卓支持庫的特征模型和目標替換代碼的特征模型進行匹配;最后對于可以進行替換的目標代碼,設(shè)計了一種涵蓋功能實現(xiàn)、頁面布局的代碼替換建議生成方法。

        本文方法仍然有一些不足的地方,需要在后續(xù)工作中不斷完善。第一,目前只是針對安卓觸摸類控件進行替換分析,對于支持庫中的其他功能目前還無法做到替換分析;第二,本文方法的實現(xiàn)與用戶交互的功能還不夠完善,后續(xù)將對該方法實現(xiàn)進行擴展,增加與用戶交互的功能。

        猜你喜歡
        特征功能方法
        也談詩的“功能”
        中華詩詞(2022年6期)2022-12-31 06:41:24
        如何表達“特征”
        不忠誠的四個特征
        當代陜西(2019年10期)2019-06-03 10:12:04
        抓住特征巧觀察
        關(guān)于非首都功能疏解的幾點思考
        可能是方法不對
        用對方法才能瘦
        Coco薇(2016年2期)2016-03-22 02:42:52
        四大方法 教你不再“坐以待病”!
        Coco薇(2015年1期)2015-08-13 02:47:34
        捕魚
        中西醫(yī)結(jié)合治療甲狀腺功能亢進癥31例
        一区二区三区四区国产99| 国产亚洲精品hd网站| 中文字幕中乱码一区无线精品| 久久久亚洲成年中文字幕| 亚洲日韩成人无码| 久久九九国产精品怡红院| 久久久99精品成人片中文字幕| 一区二区三区精品婷婷| 亚洲视频网站大全免费看| 亚洲av成人中文无码专区| 国产欧美一区二区成人影院| 国产精品av免费网站| 午夜被窝精品国产亚洲av香蕉 | y111111少妇影院无码| 中文字幕偷拍亚洲九色| 亚洲国产精品婷婷久久| 又大又紧又粉嫩18p少妇| 999国产精品亚洲77777| 日本高清长片一区二区| 精品人妻av区乱码色片| 六月婷婷久香在线视频| 色www亚洲| 亚洲一二三四五中文字幕| 无码国产精品一区二区av| 久久亚洲中文字幕无码| 波多吉野一区二区三区av| 国产精品白浆一区二区免费看| 亚洲国产日韩精品一区二区三区| 国产成人精品午夜福利在线| 美女草逼视频免费播放| 国产免费牲交视频| 久久99精品国产99久久6男男| 国产精品不卡无码AV在线播放| 国产成人国产三级国产精品| 无码av一区二区大桥久未 | 亚洲精品女同一区二区三区| 人妻少妇偷人精品无码| 国产亚洲精品自在久久蜜tv | 国产l精品国产亚洲区久久| 久久91综合国产91久久精品| 国产一区二区三区成人av|