陳 煜,周榮輝
(西南交通大學(xué) 信息科學(xué)與技術(shù)學(xué)院,成都 610031)
在移動終端技術(shù)與互聯(lián)網(wǎng)不斷發(fā)展與融合的今天,手機已從簡單的通話工具發(fā)展為集PDA、互動游戲、高分辨率攝像、移動視聽于一體的全功能通信、數(shù)據(jù)處理工具,手機上的信息存儲量也越來越多。但Android平臺自身并不提供資源管理器功能,提供的應(yīng)用程序接口(API)很簡單。因此,需要開發(fā)實用的Android手機文件管理器,以滿足廣大用戶對資源管理的需求。
Android是基于Linux 2.6內(nèi)核的開源手機操作系統(tǒng),其全面的計算服務(wù)和豐富的功能支持,完全有能力擴展到移動電話市場以外,發(fā)展前景非常廣闊。
Android 的系統(tǒng)架構(gòu)主要分為4層[1],從高到低分別是:(1)由運行在Dalvik 虛擬機上的應(yīng)用程序組成的應(yīng)用層;(2)由開發(fā)人員可以直接調(diào)用的組件所組成的應(yīng)用框架層;(3)對應(yīng)用框架層提供支撐的系統(tǒng)運行庫層;(4)包括驅(qū)動模型、內(nèi)存管理、進程管理、網(wǎng)絡(luò)協(xié)議棧等組件的Linux內(nèi)核層,它依賴于 Linux 2.6 內(nèi)核,也同時作為硬件和軟件棧之間的抽象層。根文件系統(tǒng)使用rootfs,數(shù)據(jù)及文件使用yaffs2,是專門為NAND和NOR存儲器設(shè)計驅(qū)動的文件系統(tǒng)。文件管理器在整個Android系統(tǒng)架構(gòu)中的層次如圖1。
圖1 文件管理器在整個系統(tǒng)中的架構(gòu)層次
類似于PC中的資源管理器,為實現(xiàn)用戶對于手機文件資源管理的需求,手機文件管理器需要實現(xiàn)的功能主要有文件系統(tǒng)瀏覽,目錄跳轉(zhuǎn),對文件執(zhí)行復(fù)制、移動等文件管理操作,調(diào)用其他應(yīng)用對特定文件執(zhí)行相關(guān)操作,文件搜索,文件管理器參數(shù)設(shè)置及其它設(shè)置桌面快捷方式、設(shè)置鈴聲等輔助功能。文件管理器的手機用戶用例圖如圖2。
圖2 手機用戶用例圖
本應(yīng)用基于Android SDK 2.1 平臺,以Eclipse為集成開發(fā)環(huán)境,選擇Android上層應(yīng)用開發(fā)通用的Java語言,通過Android SDK自帶的adb工具和emulator模擬器實現(xiàn)程序的調(diào)試和運行。
根據(jù)系統(tǒng)的功能需求,文件管理器主要由3個界面組成,它們分別是作為應(yīng)用主界面的FilerActivity、進行參數(shù)設(shè)置的FilerPreferences-Activity以及進行文件搜索的SearchActivity。
listview 是Android開發(fā)中最常用的組件之一,它通過一個適配器(adapter)以列表項的形式顯示指定的數(shù)據(jù),通過使FilerActivity繼承自ListActivity,可以滿足用戶方便直觀地瀏覽Android文件系統(tǒng)內(nèi)容的要求。適配器是用來把數(shù)據(jù)映射到listview上的中介,通過setListAdapter()函數(shù)可以實現(xiàn)當(dāng)前l(fā)istview與指定適配器的聯(lián)系。為了更靈活地實現(xiàn)本應(yīng)用中界面的自定義效果,在FilerActivity活動中定義一個繼承自Android.ArrayAdapter的適配器FileListAdapter,在其中的構(gòu)造函數(shù)中指定主界面listview中每一行布局的xml文件,同時新建getView()函數(shù)以覆蓋父類中的同名函數(shù),在其中實現(xiàn)布局id與指定資源數(shù)據(jù)的綁定,使主界面上顯示達到的效果。
通過對Android listview的分析可以發(fā)現(xiàn)[2],listview的顯示是以行為單位進行的,而整個屏幕列表項的顯示是由RelativeLayout.onLayout()函數(shù)中的for循環(huán)來控制實現(xiàn)的。在一次循環(huán)的執(zhí)行過程中,會依次調(diào)用ListView.makeAndAddView()、AbsListView.obtainView()、Adapter.getView()等函數(shù),最后調(diào)用執(zhí)行文件管理器程序中自定義的getView()函數(shù),覆蓋了父類listview中布局id與資源文件的綁定操作,這也是在程序開發(fā)中重寫適配器及getView()函數(shù)的目的,如圖3。
圖3 listview創(chuàng)建過程中的函數(shù)調(diào)用關(guān)系
在應(yīng)用實現(xiàn)中,無論是文件系統(tǒng)不同目錄之間的跳轉(zhuǎn),還是從其他界面的返回,或是對SD卡狀態(tài)的動態(tài)響應(yīng),都需要及時刷新文件管理器界面,同樣也會多次間接地調(diào)用自定義的getView()函數(shù)。如前所述,listview通過for循環(huán)完成當(dāng)前界面上多個view的填充操作后,隨著一些后續(xù)工作的完成,就可以看到文件系統(tǒng)中當(dāng)前目錄下的內(nèi)容,如圖4。文件管理器此時進入消息循環(huán)狀態(tài),用戶可能的下一步操作及對應(yīng)的處理函數(shù)如表1。
選項菜單(OptionsMenu)和上下文菜單(ContextMenu)是Android開發(fā)中最常見的元素,為某些操作提供了合適的入口。開發(fā)人員只需預(yù)先設(shè)計好相應(yīng)的菜單選項,以xml文件的形式存放,在隨后執(zhí)行系統(tǒng)回調(diào)函數(shù)的過程中進行有選擇的顯示菜單項即可。相比而言,ContextMenu更適合設(shè)置一些與單個view項操作相關(guān)的菜單項,OptionsMenu適合設(shè)置一些與整體相關(guān)的選項。在這里,可以把文件重命名、查看屬性、設(shè)置鈴聲等操作放在ContextMenu中實現(xiàn),而搜索文件、排序設(shè)置等操作就由OptionsMenu來完成。
圖4 文件管理器主界面效果圖
表1 用戶的界面操作與對應(yīng)的處理函數(shù)
在Android本身的實現(xiàn)中,大量用到了PreferenceActivity對系統(tǒng)進行信息配置和管理。文件管理器的開發(fā)中,也同樣使用FilerPreferences-Activity為用戶提供參數(shù)設(shè)置的接口。它的布局文件放在固定的路徑res/xml下。由FileActivity中OptionsMenu中的一個菜單項來啟動。
另外,文件管理器還提供了文件搜索的功能,即能夠根據(jù)關(guān)鍵字依次匹配指定目錄下的文件/文件夾名稱,并以列表形式顯示出搜索的結(jié)果,該功能由SearchActivity來實現(xiàn)。Android的搜索功能能夠幫助開發(fā)者很好地管理搜索對話框,使開發(fā)人員不需要自己去開發(fā)一個搜索框,不需要考慮把搜索框放在什么位置、搜索框是否會影響當(dāng)前的界面等不重要的細(xì)節(jié)問題,所有這些工作都由搜索管理器(SearchManager)來輔助實現(xiàn)。當(dāng)在Android搜索欄中輸入關(guān)鍵字執(zhí)行搜索操作時,搜索管理器將使用一個專門的Intent“android.intent.action.SEARCH”,將它傳給在配置文件Android-Manifest.xml中聲明的處理搜索結(jié)果的activity,即本應(yīng)用中的SearchActivity。通過get-Intent().getStringExtra()函數(shù)即可獲得用戶輸入的關(guān)鍵字,然后按關(guān)鍵字執(zhí)行搜索操作,并以列表形式顯示出得到的結(jié)果。在程序中建立了int類型的變量mFileNumber來記錄已找到搜索目標(biāo)個數(shù),用ArrayList
圖5 文件搜索過程流程圖
Android應(yīng)用開發(fā)中,每一個界面即對應(yīng)著一個activity。用戶在使用手機軟件時,需要在不同的界面之間來回轉(zhuǎn)換。相對應(yīng)的程序中的每一個activity都有開始和結(jié)束的過程。
可以在配置文件AndroidManifest.xml中聲明應(yīng)用包含的所有活動及每個活動所要響應(yīng)的intent,然后在程序中需要的地方用startActivity()函數(shù)向系統(tǒng)發(fā)送指定的intent,由系統(tǒng)啟動合適的活動響應(yīng)intent。在程序中,用Activity.finish()函數(shù)結(jié)束當(dāng)前活動,由活動管理器(Activity Mana-ger)確定下一個進程的到來。在文件管理器的整個應(yīng)用中,各個activity之間的轉(zhuǎn)換如圖6。步操作。
圖7 文件復(fù)制操作時序圖
表2 程序調(diào)用文件管理的主要系統(tǒng)函數(shù)
另外,在設(shè)計中,還應(yīng)該把對文件進行處理的過程放在一個新建的子線程中執(zhí)行,以取得較好的界面顯示效果。
控制部分的文件復(fù)制操作時序圖如圖7。
圖6 應(yīng)用中各個activity之間的轉(zhuǎn)換
本應(yīng)用要實現(xiàn)的文件管理功能主要有單個或批量文件的移動、復(fù)制、重命名等操作。針對應(yīng)用的具體情況,在界面底部建立了一個工具欄(包括yankbar、copybar、movebar),配合listview中各行的icon按鈕,更方便地完成對文件管理的大部分操作。
MVC(Model-View-Controller)是當(dāng)前比較流行的軟件開發(fā)框架,它的思想與觀察者模式類似。Android項目整體就是一種典型的MVC結(jié)構(gòu),其中廣泛使用的xml布局文件即是view,activity和intent,起到了控制器的作用,提供者對數(shù)據(jù)層做了良好的封裝,而且提供者把數(shù)據(jù)管理的范疇從數(shù)據(jù)庫泛化到了數(shù)據(jù)的概念[3]。通過使用MVC模式,可以使文件管理器的界面設(shè)計工作和文件系統(tǒng)相關(guān)處理操作相互獨立,讓界面的設(shè)計更加靈活,文件管理功能也可以進行模塊化的開發(fā)。同時也能夠使開發(fā)人員專心處理前端界面顯示與后臺文件系統(tǒng)數(shù)據(jù)之間的關(guān)系,設(shè)計出高效穩(wěn)定的程序。
就本應(yīng)用來說,可以事先單獨設(shè)計好每個界面布局的xml文件并根據(jù)實際情況進行修改和調(diào)整,文件的復(fù)制、移動等調(diào)用系統(tǒng)文件操作函數(shù)接口的后臺操作就是邏輯模型部分,控制部分表現(xiàn)在各個activity的生命周期中控制應(yīng)用界面的各種邏輯切換,以及相關(guān)數(shù)據(jù)結(jié)構(gòu)的變化,調(diào)用對應(yīng)的處理函數(shù)等。文件管理操作中,控制部分的界面變化比較復(fù)雜,如在選取或取消要操作的目標(biāo)文件、進入新的目錄選擇文件、在執(zhí)行復(fù)制或移動等操作的過程中、文件管理操作成功或失敗的處理并返回等等情況,listview界面及底部的操作工具欄都要隨之刷新并正確地顯示,指示用戶進行下一
在程序中,建立了File類型的全局變量mCur-Dir,存放將要進入或正在顯示的目錄信息;ArrayList
在文件管理器的數(shù)據(jù)存儲中,使用了Android的3種數(shù)據(jù)存儲方式:SharePreference、SQLite和ContentProvider。
SharePreferenc常用于存儲較簡單的參數(shù)設(shè)置,文件管理器中FilerPreferencesActivity活動就是用這種方式,通過preferences.xml文件來持續(xù)化應(yīng)用配置信息的。當(dāng)應(yīng)用剛安裝好第一次運行時,配置文件為空,使用默認(rèn)的數(shù)據(jù)給參數(shù)賦值,對應(yīng)用進行配置,當(dāng)執(zhí)行FilerPreferences-Activity活動中的addPreferences-FromResource(R.xml.preferences)后,將在/data/data/chenyu.filemanage.filer/中建立一個以應(yīng)用包名為前綴的preferences.xml文件,保存應(yīng)用的配置數(shù)據(jù)信息,可以通過adb工具查看文件的內(nèi)容,如圖8。
圖8 用adb工具查看配置文件內(nèi)容
在使用文件管理器的過程中,用戶可以通過FilerPreferencesActivity的界面對參數(shù)設(shè)置的內(nèi)容進行查看或修改。應(yīng)用在activity退出時對相關(guān)的配置信息數(shù)據(jù)進行提交,保存在preferences.xml文件中,使用戶的設(shè)置在下次使用應(yīng)用時依然有效。
文件管理器中使用的SQLite數(shù)據(jù)庫保存的信息為每種類型文件的幾個屬性(extension,mimetype,icon, action等)的對應(yīng)關(guān)系,數(shù)據(jù)庫文件位于/data/data/chenyu.filemanage.filer/lib中。在應(yīng)用中主要有2個地方要對數(shù)據(jù)庫進行查詢使用。(1)listview的界面顯示,雖然每一行view由適配器確定的布局都是一樣的,但實現(xiàn)時也要根據(jù)不同文件的類型,顯示不同的資源標(biāo)示圖片以對不同類型的文件進行區(qū)分;(2)在對特定文件執(zhí)行打開操作時,需要向系統(tǒng)發(fā)送包括type、action等參數(shù)在內(nèi)的intent消息,這些信息也都需要查詢數(shù)據(jù)庫得到。
文件管理器中已經(jīng)事先設(shè)置了比較多的數(shù)據(jù)庫元組,它涵蓋了如今大部分常見的手機文件類型,用戶也可以在設(shè)置界面中添加或修改對應(yīng)的文件屬性信息。
在SQLite數(shù)據(jù)庫的操作中使用了Content-Provider和ContentResolver,嚴(yán)格來說,它并不是真正的實現(xiàn)數(shù)據(jù)存儲,而是一種提供數(shù)據(jù)共享及訪問的手段。在自定義的繼承自ContentProvider的類中封裝好了數(shù)據(jù)庫中的數(shù)據(jù),同時重新定義了插入、刪除、查詢等成員函數(shù),對外提供一個公共的統(tǒng)一資源標(biāo)示符(URI)。其他需要訪問數(shù)據(jù)的地方就可以通過ContentResolver函數(shù),傳入這個URI,對數(shù)據(jù)進行訪問。通過研究程序源碼可以發(fā)現(xiàn),ContentResolver的數(shù)據(jù)獲取方法,如query(),調(diào)用的還是對應(yīng)ContentProvider的query()方法。而ContentProvider的query()為抽象方法,我們在自定義的子類中已經(jīng)重寫了該成員函數(shù)方法,這樣,當(dāng)調(diào)用ContentResolver.query()方法時,執(zhí)行的還是應(yīng)用中自己寫的MimeProvider.query方法。也就是說,我們在定義數(shù)據(jù)提供者MimeProvider的同時也定義了外界訪問這個封裝數(shù)據(jù)集的接口,只不過這些已定義訪問的方法是由Content-Resolver的成員函數(shù)間接調(diào)用而已。
本文從實際應(yīng)用出發(fā),設(shè)計了一款實用、高效的手機文件管理器。通過靈活運用Android開發(fā)的相關(guān)技術(shù),成功解決了實現(xiàn)過程中遇到的技術(shù)問題,也為同類Android應(yīng)用開發(fā)提供了較好的參考。Android的開源為開發(fā)人員解決各種問題提供了極大的方便,隨著手機廠商不斷的加入Android陣營和用戶使用量的日益增多,Android應(yīng)用開發(fā)的明天將會更加美好。
[1]楊豐盛. Android技術(shù)內(nèi)幕:系統(tǒng)卷[M]. 北京:機械工業(yè)出版社,2011.
[2]Fan Jiang, Shaoping Ku.How to Display the Data from Database by ListView on Android[C]. 2nd International Workshop on Intelligent Systems and Applications, 2010:1-4.
[3]Hyun Jung La,Soo Dong Kim.Balanced MVC Architecture for Developing Service-Based Mobile Applications[C].7th International Conference on e-Business Engineering , 2010:292-299.
[4]王世江,余志龍,陳昱勛,鄭名杰. Google Android SDK開發(fā)范例大全[M]. 2版 北京:人民郵電出版社,2010.