朱亞迪 吳毅堅 趙文耘
(復旦大學軟件學院 上海 201203)(上海市數據科學重點實驗室(復旦大學) 上海 200437)
?
基于代碼片段復用的安卓應用組裝技術研究
朱亞迪 吳毅堅 趙文耘
(復旦大學軟件學院 上海 201203)(上海市數據科學重點實驗室(復旦大學) 上海 200437)
安卓系統的開放性和安卓應用開發的較低的技術門檻,吸引了大量開發者加入到安卓應用開發陣營中來。在編碼過程中,開發者需要兼顧界面設計和業務邏輯,并手工維護他們的一致性;相似的界面、類似的邏輯也需要開發者手工進行“復制-粘貼”式的開發。提出安卓應用界面和業務邏輯的結構模型,以統一的方式描述安卓應用的界面元素、業務邏輯以及兩者的關聯,支持將安卓應用的界面代碼和業務邏輯代碼對應起來。提出可配置的安卓應用結構化描述和組裝方法,使得開發人員可以以書寫配置文件的方式從業務層面描述應用,并支持界面和業務邏輯代碼片段的組裝,從而快速構建符合需求的安卓應用。設計了安卓應用開發實驗來驗證所提方法及技術的有效性。
安卓應用 結構模型 代碼片段 復用
安卓系統的開放性和安卓應用開發的較低的技術門檻,吸引了大量開發者加入到安卓應用開發陣營中來。隨著安卓應用開發者數量的不斷增加,各類安卓應用市場中不斷涌現出大量的移動應用,覆蓋了人們日常生活中的各個領域。然而,在安卓應用不斷豐富、開發者陣營不斷擴張的環境下,安卓應用開發的過程和方法卻仍然以“從頭開發”或者代碼的“復制-粘貼”為主。在編碼過程中,開發者需要兼顧界面設計和業務邏輯,并手工維護他們的一致性;一些相似的界面、類似的邏輯也需要開發者手工進行“復制-粘貼”式的開發。這種看上去自由、簡單的開發方式,導致開發者需要花大量的精力處理開發技術細節,而不能專注于業務本身。如何提升安卓開發人員編碼工作的標準化程度,促進領域業務代碼的復用,對提升安卓應用開發效率和產品質量有著重要的意義。
安卓應用多運行于移動設備上,移動設備(特別是手機)的顯示區域有限,因此大量的應用實際上是遵循一定的設計模式,并且移動應用軟件規模小[19],其復雜性比傳統的Web應用和桌面應用大大降低。這就給安卓應用的標準化開發和基于復用的開發提供了可能。
本文提出安卓應用界面和業務邏輯的結構模型,以統一的方式描述安卓應用的界面元素、業務邏輯以及兩者的關聯關系,從而支持將安卓應用開發過程中的界面代碼和業務邏輯代碼對應起來,降低開發人員人工維護的難度。提出可配置的安卓應用結構化描述和組裝方法,使得開發人員可以以書寫配置文件的方式從業務層面描述應用,并支持界面和業務邏輯代碼片段的自動組裝,從而快速構建符合需求的安卓應用。基于該方法,實現了一個代碼組裝工具,輔助開發者快速創建安卓應用項目。
為了驗證所提方法及技術的有效性,設計了一套安卓應用開發實驗。實驗結果表明,和傳統開發方式相比,本文的方法和相應的工具對提高安卓應用開發效率是有幫助的。
1.1 方法概述
安卓應用由于受到顯示區域大小的限制,特定模塊的界面和業務功能相對簡單。因此,我們提出安卓應用界面和業務邏輯的結構模型,以統一的方式描述安卓應用的界面元素、業務邏輯以及兩者的關聯關系。將界面元素和業務邏輯的實現代碼以代碼片段的形式提取出來,并保存在代碼庫中。開發人員依據結構模型編寫配置文件對應用模塊的界面和業務邏輯進行描述,然后使用代碼組裝工具對代碼片段進行組裝,生成安卓應用框架代碼。開發人員在此基礎上完善核心代碼,最終得到可運行的安卓應用。
需要注意的是本文方法關注于安卓應用中的特定模塊,即單個Activity所包含的界面和業務邏輯。并且生成的是應用模塊的框架代碼,具體的業務邏輯還需要開發人員手工實現。
1.2 安卓應用結構模型
安卓應用結構模型如圖1所示。

圖1 安卓應用結構模型
圖1中的安卓應用結構模型描述了應用模塊中可能包含的界面元素和業務邏輯,以及兩者之間的關系。下面對結構模型中的關鍵元素進行介紹:
UI:界面元素的總稱。用name來唯一表示該元素,并且有一組屬性attrs集合用于對界面元素進行描述,map中第一個string表示屬性名,第二個string表示屬性值。界面元素又可以分為可見的界面元素和不可見的界面元素。
Invisible Component:不可見的界面元素,是界面元素的容器,構成模塊界面的框架。不可見的界面元素主要有Container。
Visible Component: 可見的界面元素。是界面中與用戶進行交互的基本單位。可見的界面元素要嵌入不可見的界面元素中才能展示出來,這符合安卓應用開發的習慣。可見的界面元素包括Button(按鈕)、Input(輸入框)、List(列表)、GesturePassword(手勢密碼)、EncryptInput(加密輸入框)、PhoneCode(手機驗證碼輸入框)、PicCode(圖片驗證碼輸入框)等。
BusinessLogic:業務邏輯。負責處理用戶與界面元素的交互以及相關的業務。有StoreToLocal(存儲到本地)、ValidateInput(對輸入的內容進行驗證)和ClickEvent(處理點擊事件)等。
Dependency:業務邏輯的依賴。包括一些安卓應用權限的配置和庫的依賴,在開發過程中需要在AndroidManifest.xml和build.gradle文件(本文使用的安卓開發環境為Android Studio)聲明,比如對文件進行存儲時需要添加WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE權限。
CodeSnippet:代碼片段。是界面元素和業務邏輯的具體實現代碼,分別為視圖代碼片段和業務代碼片段。代碼片段是應用開發者在開發過程中編寫的一些設計良好的代碼,對視圖代碼片段進行組合能夠形成布局文件,即應用的界面;而業務代碼片段可能只是業務邏輯的框架代碼,需要開發者再此基礎上實現具體的業務邏輯。
CodeRepository:代碼庫。用于對代碼片段進行存儲、管理。
Module:安卓應用中的模塊。一個模塊包含若干界面元素和業務邏輯,并用name來唯一表示,description對模塊實現的功能進行描述。
Constraint:約束條件。對模塊中界面元素的組合嵌套規則進行描述,比如最基本的規則是可見的界面元素要嵌入容器中才能展示出來,具體的規則還要根據模塊所要實現功能的業務約束來制定。
Configuration:配置文件。表示某一個模塊的具體實現,反映出模塊的實現包含了哪些界面元素和業務邏輯,以及界面元素和業務邏輯之間的關聯。配置文件中activity和layout分別是需要生成的Activity和布局文件名稱,description是相關描述信息。
1.3 代碼組裝流程
基于代碼片段復用的安卓應用組裝流程示意如圖2所示。其中視圖代碼片段、業務代碼片段、代碼庫、配置文件分別對應于安卓應用結構模型中的相應元素。

圖2 代碼組裝流程示意圖
視圖代碼片段和業務代碼片段分別是結構模型中視圖元素和業務邏輯的實現代碼。配置文件由結構模型中的界面元素和業務邏輯組成,并建立起結構模型與代碼片段之間的對應關系。代碼組裝工具根據配置文件對代碼片段進行組裝,生成安卓應用代碼。需要注意的是組裝工具生成的是應用的框架代碼,需要開發人員在此基礎上完善代碼,最終得到可運行的應用。
1) 代碼片段和代碼庫
代碼片段是應用開發過程中由開發人員編寫的滿足某一功能需求的代碼。代碼片段分為兩種:來自布局文件的視圖代碼片段和來自Activity的業務代碼片段。視圖代碼片段可能是設計良好的輸入框、按鈕等,可能對應于單個界面元素也可能對應于多個界面元素;業務代碼片段可能是對輸入的內容進行校驗的代碼、處理用戶點擊事件的代碼等。
代碼庫負責對代碼片段進行存儲、管理。初始時代碼庫為空,在應用開發過程中,會產生一些設計良好的代碼,開發人員將這些代碼提取為代碼片段,加入代碼庫中,便于以后復用。
2) 配置文件
配置文件是由開發者根據需求和安卓應用結構模型來編寫的,對應用的界面和功能進行描述。需求最終要實現為應用代碼,而配置文件則介于需求和應用代碼之間,比需求更形式化而又比代碼更簡單,具有簡潔、直觀、便于修改的特點。配置文件以XML的格式存在,其內容構成一棵文檔樹,樹中的節點對應于結構模型中的界面元素或業務邏輯元素。通過編寫配置文件來滿足可變性需求,由代碼組裝工具根據配置文件對代碼片段進行組裝生成應用代碼,達到代碼復用的目標。
3) 模板
模板是一個包含了占位符的Activity。Activity有多個生命周期[14],應用的業務邏輯需要在特定的生命周期實現,即業務代碼片段要插入到相應的生命周期的相應位置處,因此需要在Acitivity模板中不同生命周期的不同位置預留占位符。下面代碼預留了$ActivityName、$Activity、$View和$onCreate 四個占位符:
public class $ActivityName extends Activity {
$Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.$View);
ButterKnife.bind(this);
$onCreate
}
}
4) 代碼組裝工具
代碼組裝工具根據配置文件對代碼塊進行組裝生成應用代碼,組裝過程就是完成對配置文件中文檔樹的遍歷,根據配置文件中的節點類型進行如下操作:
(1) 對于配置文件文檔樹中的Configuration節點,根據節點的layout和activity屬性值生成空白的布局文件和Activity模板文件。
(2) 對于配置文件文檔樹中的界面元素,根據元素的name屬性值在代碼庫中進行檢索,得到匹配的視圖代碼片段,依照配置文件文檔樹的結構,對代碼片段進行組裝,形成模塊對應的布局文件。
(3) 對于配置文件文檔樹中的業務邏輯元素,根據元素的name屬性值在代碼庫中進行檢索,得到匹配的業務代碼片段,按照該業務代碼片段中position的值將其插入到Activity模板中相應位置處。
上述操作中一個主要過程是根據配置文件文檔樹T1構建布局文件文檔樹T2。最終T2與T1有相同的結構,對于T1中某一界面元素E1,在T2中對應位置節點為E2,E2是代碼庫中與E1對應的視圖代碼片段。根據T1構建T2的過程中用到兩個隊列:Queue1和Queue2。Queue1中隊首E1為T1中當前待處理的布局文件中的節點,Queue2中隊首元素E1'為與E1對應的E2的父節點。代碼生成工具根據E1從代碼庫中檢索,得到與E1相匹配的代碼片段E2,將E2作為E1'的子節點插入到T2中。整個過程的偽代碼如下:
read configure file and generate layout and activity file
root = configure.getSubElement()
//獲取配置文件中Configuration節點的子節點
Queue1.enqueue(root)
//使用隊列來對配置文件分層遍歷
Queue2.enqueue(templateRoot)
//模板根節點入隊
while Queue1 is not empty{
node1 = Queue1.dequeue()
node2 = Queue2.dequeue()
if node1 is a view {
code = findView(node1)
//在代碼庫中檢索匹配對應的視圖代碼片段
if code is null{
//如果找不到代碼則生成注釋
generate comment
}else{
node2.append(code)
//將實現代碼片段插入生成的布局文件
//如果該節點是容器界面元素,需要將其包含的子節點加入隊列
if node1 is a container{
for each subelement of node1{
Queue1.enqueue(subelement)
Queue2.eneuque(code)
}
}
}
}else if node1 is a logic {
code = findLogic(node1)
//查找對應的業務代碼片段
if code is null{
generate comment
}else{
insert code into activity by position
//將業務代碼片段插入生成的activity文件
}
}
}
上述代碼中findView()和findLogic()通過配置文件中界面元素和業務邏輯元素的name屬性值與代碼庫中代碼片段的name屬性值進行匹配,如圖3所示。

圖3 配置文件與結構模型和代碼片段之間對應關系
2.1 工具實現
我們使用Swing技術實現了一個基于代碼片段復用的代碼組裝工具。開發人員依據業務需求編寫配置文件,代碼組裝工具依據配置文件對代碼庫中的代碼片段進行組裝,得到應用的框架代碼。開發人員在此基礎上完善代碼,最終得到可運行的應用代碼。
2.2 實驗和評價
為了驗證所提方法和所開發工具的有效性,我們設計了一套安卓應用開發實驗。實驗中我們選取了兩名計算機軟件專業的研究生,他們安卓應用開發水平相當,分別作為實驗組和對照組。他們被要求依次完成7個安卓應用登錄功能的實現。在開發的過程中,實驗組使用本文給出的代碼組裝工具,可以將開發過程中的代碼片段保存入代碼庫中,并在后續開發任務中編寫配置文件。然后使用工具對代碼片段進行組裝,生成框架代碼,在此基礎上完善代碼。對照組不使用工具,可以使用手工進行“復制-粘貼”的方式開發。
實驗組和對照組使用的開發環境都為安卓官方集成開發環境Android Studio,版本為1.5.0.0。實驗中一共有7個開發任務,開發者每次新建一個空白安卓項目,Android Studio將自動生成項目的相關文件,然后將該項目加入Git并提交代碼。開發者完成每個開發任務后再次提交代碼,Git將統計出開發者為了完成開發任務而編寫的代碼行數(包括實驗組配置文件代碼行數)。實驗結果如圖4所示。

圖4 代碼行數統計圖
從圖4中可以看出,采用本文提出的方法和工具能夠有效地減少開發者的代碼量。本文方法和工具對于應用開發者的幫助體現在以下幾點:
(1) 可行性。在實驗中,實驗組使用配置文件對開發需求進行描述,然后使用代碼組裝工具對代碼片段進行組裝生成代碼框架,最后開發者對代碼框架進行代碼填充,最終實現為一個可運行的應用。
(2) 提高代碼質量。可復用的代碼片段具有結構化程度高,易于理解的特點。將可復用的代碼片段提取出來并復用到應用開發中有助于提高代碼質量。
然而,上述實驗有一定的局限性。首先,參與實驗的開發人員數量太少;其次,收集的實驗數據太少。
為了提高安卓應用開發的效率,很多組織和研究人員致力于通過代碼生成技術生成安卓應用代碼。
Android Bootstrap[1]是一個集成了大量模板(包括UI、網絡請求庫、賬戶管理等)的安卓應用在線生成工具。使用者只需要輸入應用的包名,Android Bootstrap就能生成一個完整的項目,該項目中包含了安卓應用開發中一些常用的模塊如登錄、滾動的圖片、網絡請求、Json數據解析以及一些預定義的主題和UI元素(按鈕和輸入框等)等。然而,Android Bootstrap的整個輸入只有一個包名,不支持根據應用的需求進行定制,應用的界面和業務邏輯還需要開發者手工完成。
App Inventor[2]是MIT研發的旨在為所有人,特別是年輕人,展示軟件開發的魅力,讓他們從軟件消費者轉變為軟件創造者的開源項目。App Inventor提供一個在線開發工具,以圖形化的控件來對應用的組件和行為進行表示。使用者通過拖拽控件,像搭積木一樣拼湊出一個安卓應用。然而,使用App Inventor開發出的應用與實際應用相比仍有很大差距。
Markus Aleksy[3]從用戶界面和功能兩方面對應用建立原型,然后復用現有應用的組件來快速開發安卓應用。然而并沒有給出如何獲取現有應用組件的方法,缺乏對應用組件的管理和維護。
Khambati等[4]創造了一種可視化模型語言[13],使用可視化的模型語言編寫配置文件對應用進行描述,并開發出了一個安卓應用生成工具,該工具以配置文件作為輸入,生成與醫療保健計劃相關的安卓應用。然而該可視化模型語言是針對醫療保健專家而設計的,不是針對安卓應用開發者。另外,使用該工具生成的是安卓應用的安裝文件,開發者無法對應用進行修改。
Nguyen等[5]開發出一個能夠生成主從模式安卓應用的工具。Li等[6]提出了一種搜索平臺,該平臺能夠搜索安卓應用的界面元素,幫助開發者識別應用中的界面元素,但他們沒有給出有效地復用這些界面元素的方法或技術。
Lachgar等[7]采用模型驅動架構的方法設計出一種領域特定語言,在此基礎上開發出一個工具,該工具能夠生成安卓應用的用戶界面。Sabraoui等[8,9]也采用模型驅動架構的方法,設計出基于UML的應用界面生成工具,該工具能夠針對不同移動操作系統(iOS、Android、Windows Phone、BlackBerry)生成相應的應用界面。然而上述研究工作生成的應用界面非常簡單,并沒有考慮到實際應用開發中應用界面的復雜性,不能真正地幫助應用開發者進行快速開發,并且缺乏對應用業務邏輯的支持。
Mojica等[10]借鑒軟件產品線和特征模型[11]技術,對安卓系統中的組件進行建模,如Service是運行在后臺并且沒有用戶界面的組件,Activity是一個擁有用戶界面并能與用戶進行交互的組件。通過定義領域特定語言來對安卓應用的組件和組件之間的關系進行描述,其語法類似Java語言中類的定義,然后開發出代碼生成工具AndroidModeler來生成安卓應用的框架代碼。然而他們并未對應用的界面進行考慮,并且其定義的領域特定語言語法過于簡單,描述能力非常有限,無法對組件的具體功能進行詳細的描述。
Barnett等[12]借鑒模型驅動技術能夠提高軟件開發效率降低成本的特點,開發出一個工具RAPPT,使用領域特定語言來描述安卓應用,進而生成安卓應用工程的框架代碼。使用RAPPT生成的工程能夠直接導入安卓官方集成開發環境Android Studio。然而開發人員還需要進一步調整生成應用的界面代碼,并且RAPPT不支持對應用界面和功能的靈活配置,只能生成與模板應用類似的應用。
一些研究人員對安卓應用的相似性進行了研究。王浩宇等[15]基于代碼克隆檢測技術對安卓應用進行特征提取,分析應用之間的相似度。閆晉佩等[16]對第三方應用市場中的安卓應用二進制文件中類和方法的相似性進行計算,以此來識別應用重打包。張希遠等[17]使用CCFinder工具對應用市場中應用模塊代碼的相似度進行了研究。焦四輩等[18]提出一種能夠識別經過代碼混淆后安卓應用相似性的方法。
本文針對安卓應用的特點,提出安卓應用結構模型來對應用模塊的界面元素和業務邏輯進行建模。在此基礎上,使用配置文件對安卓應用模塊的界面和功能進行描述,通過代碼組裝工具對代碼片段進行組裝,生成安卓應用框架代碼,輔助開發者進行快速開發。
然而,本文提出的安卓應用結構模型還不夠完備,不足以描述安卓應用的全貌。采用了XML格式的配置文件來對安卓應用進行描述,而XML中有太多與語義無關的符號如尖括號和引號等。配置文件需要開發人員手工編寫,不夠方便。在今后的研究中應該提出其他形式的領域特定語言來對安卓應用進行描述。另外,本文的實現工具仍處于原型階段,在實際應用中還有很多局限性,需要進一步完善,最終開發出能夠滿足實際安卓應用開發需求的工具。
[1] Android Bootstrap[EB/OL].[2016-1-1].http://www.androidbootstrap.com/.
[2] App Inventor[EB/OL].[2016-3-20].http://appinventor.mit.edu/explore/get-started.html.
[3] Aleksy M.An Approach to Rapid Prototyping of Mobile Applications[C]//Proceedings of the 27th IEEE International Conference on Advanced Information Networking and Applications (AINA),2013:1072-1077.
[4] Khambati A,Grundy J,Warren J,et al.Model-Driven Development of Mobile Personal Health Care Applications[C]//Proceedings of the 23rd IEEE/ACM International Conference on Automated Software Engineering,2008:467-470.
[5] Nguyen T,Vanderdonckt J.User Interface Master Detail Pattern on Android[C]//Proceedings of the 4th ACM SIGCHI Symposium on Engineering Interactive Computing Systems,2012:299-304.
[6] Li Kaiyuan,Xu Zhensheng,Chan Xiangping.A Platform for Searching UI Component of Android Application[C]//Proceedings of 5th International Conference on Digital Home (ICDH),2014:205-210.
[7] Lachgar M,Abdali A.Generating Android graphical user interfaces using an MDA approach[C]//Proceedings of the 2014 Third IEEE International Colloquium in Information Science and Technology (CIST),2014:80-85.
[8] Sabraoui A,Koutbi M E,Khriss I.GUI code generation for Android applications using a MDA approach[C]//International Conference on Complex Systems (ICCS),2012:1-6.
[9] Sabraoui A,Koutbi M E,Khriss I.A MDA-Based Model-Driven Approach to Generate GUI for Mobile Applications[J].International Review on Computers & Software,2013,8(3):844-852.
[10] Mojica I J,Adams B,Nagappan M,et al.A Large-Scale Empirical Study on Software Reuse in Mobile Apps[J].IEEE Software,2014,31(2):78-86.
[11] Ruiz I J M,Nagappan M,Adams B,et al.Understanding reuse in the Android Market[C]//Proceedings of the 20th International Conference on Program Comprehension (ICPC),2012:113-122.
[12] Barnett S,Vasa R,Grundy J.Bootstrapping Mobile App Development[C]//Proceedings of the 37th IEEE International Conference on Software Engineering (ICSE),2015:657-660.
[13] Moody D L.The “Physics” of Notations: A Scientific Approach to Designing Visual Notations in Software Engineering[C]//Proceedings of the 32Nd ACM/IEEE International Conference on Software Engineering-Volume 2,2010:485-486.
[14] Liu Jianye,Yu Jiankun.Research on Development of Android Applications[C]//Proceedings of the 2011 4th International Conference on Intelligent Networks and Intelligent Systems (ICINIS),2011:69-72.
[15] 王浩宇,王仲禹,郭耀,等.基于代碼克隆檢測技術的Android應用重打包檢測[J].中國科學:信息科學,2014,44(1):142-157.
[16] 閆晉佩,何暉,安文歡,等.國內第三方Android應用市場安全性的檢測[J].計算機科學,2015,42(12):143-147.
[17] 張希遠,張剛,沈立煒,等.多維度的安卓應用相似度分析[J].計算機科學,2016,43(3):199-205.
[18] 焦四輩,應凌云,楊軼,等.一種抗混淆的大規模Android應用相似性檢測方法[J].計算機研究與發展,2014,51(7):1446-1457.
[19] 朱洪軍,陳灝,華保健,等.移動應用代碼保護現狀與技術研究[J].計算機應用與軟件,2016,33(3):314-319,333.
ANDROID APPLICATION ASSEMBLY TECHNOLOGY STUDY BASED ON CODE SNIPPET REUSE
Zhu Yadi Wu Yijian Zhao Wenyun
(SchoolofSoftware,FudanUniversity,Shanghai201203,China)(ShanghaiKeyLaboratoryofDataScience,FudanUniversity,Shanghai200437,China)
The openness of the Android system and low threshold of Android application development attracted a large number of developers to join in the Android application development camp. In the process of coding, developers need to consider the interface design and business logic, and maintain their consistency by hand. Some similar interface and logic also need developers manually "copy-and-paste". This paper puts forward the interface and business logic structure model of Android application, and describes the Android application interface, business logic, and the relationship between them in a uniform way. The model also supports the correspondence between interface code and business logic code in the development of Android application. We propose a configurable structural description and assembly method of Android applications, which allows developers to write configuration file to describe application from the business level. The method supports the assembly of interface and business logic code snippets to help developers quickly build Android applications conforming to the requirements. In order to verify the effectiveness of the method and technology, we design a set of Android application development experiments.
Android applications Structure model Code snippets Reuse
2016-05-03。國家自然科學基金項目(61402113);國家高技術研究發展計劃項目(2013AA01A605)。朱亞迪,碩士生,主研領域:軟件復用,移動應用開發。吳毅堅,副教授。趙文耘,教授。
TP3
A
10.3969/j.issn.1000-386x.2016.11.039