到目前為止,我們已經(jīng)一同學(xué)習(xí)了Android應(yīng)用程序中的結(jié)構(gòu)與典型元素,其中包括用戶界面元素以及數(shù)據(jù)存儲(chǔ)。利用當(dāng)下已經(jīng)掌握的知識(shí),大家完全可以著手創(chuàng)建自己的Android應(yīng)用。不過(guò)在實(shí)際操作之前,我們還要梳理一遍部分常用Android組件——這也正是今天這篇文章的主要內(nèi)容。在本系列的下一篇文章中,我們將探討SDK示例代碼。
Android應(yīng)用程序當(dāng)中包含四大組件:Activity、Service、Content Provider以及Broadcast Receiver。只要大家創(chuàng)建或者使用其中的任何一種,就必須將對(duì)應(yīng)元素添加到項(xiàng)目Manifest當(dāng)中。我們之前已經(jīng)跟Activity打了不少交道,因此在今天的文章中我就不再浪費(fèi)篇幅加以介紹了?,F(xiàn)在讓我們把注意力集中在另外三種主要應(yīng)用程序組件身上。需要強(qiáng)調(diào)的是,我還將介紹大家在應(yīng)用程序當(dāng)中最可能用到的其它一些資源,其中包括fragment以及action bar。
在Android系統(tǒng)當(dāng)中,一項(xiàng)Service就相當(dāng)于一個(gè)后臺(tái)進(jìn)程。Service通常被用于那些正在進(jìn)行或者需要持續(xù)很長(zhǎng)一段時(shí)間的進(jìn)程。事實(shí)上Service并不具備用戶界面,因此它們通常需要與其它組件結(jié)合起來(lái)以實(shí)現(xiàn)功效,例如與Activity聯(lián)手。最典型的例子就是,在應(yīng)用程序當(dāng)中Activity會(huì)在用戶操作的同時(shí)啟動(dòng)一項(xiàng)Service,這項(xiàng)Service也許會(huì)將數(shù)據(jù)上傳至Web資源當(dāng)中。用戶可以繼續(xù)與該Activity進(jìn)行交互,但與此同時(shí)Service的運(yùn)作卻不受影響——因?yàn)樗膱?zhí)行一直在后臺(tái)完成。
提示:如果大家希望執(zhí)行獲取互聯(lián)網(wǎng)數(shù)據(jù)之類的后臺(tái)進(jìn)程,其中也不一定非要使用Service類。根據(jù)應(yīng)用實(shí)際需求的不同,大家可能更適合在自己的Activity中利用內(nèi)部AsyncTask類來(lái)解決問(wèn)題。它能讓后臺(tái)進(jìn)程與用戶界面徹底分離,但我們的Activity仍然可以接收來(lái)自AsyncTask的運(yùn)作結(jié)果并將其上更新至用戶界面當(dāng)中。
要將一項(xiàng)Service組件添加到Manifest當(dāng)中,我們需要利用以下語(yǔ)法及其元素取代應(yīng)用程序元素:
<service android:name=".ServiceClassName" />
大家可以在Eclipse當(dāng)中創(chuàng)建一個(gè)Service類,其過(guò)程與之前介紹過(guò)的Activity一樣、只不過(guò)這次是把Service選擇為超級(jí)類。Service與Activity組件的區(qū)別我們之前已經(jīng)談到過(guò),二者之間存在多種重大差異。如果我們以Activity為起點(diǎn)啟動(dòng)一項(xiàng)Service,而用戶又通過(guò)導(dǎo)航從該Activity切換到了其它應(yīng)用程序處,那么該Service仍將繼續(xù)運(yùn)行。因此,Service擁有的生命周期與我們所熟知的Activity完全不同,大家需要將這一點(diǎn)牢記于心、從而確保自己的應(yīng)用程序能夠有效運(yùn)轉(zhuǎn)。
其它應(yīng)用程序組件可以與Service綁定,并向其請(qǐng)求并接收數(shù)據(jù)。如果一項(xiàng)綁定Service正處于運(yùn)行當(dāng)中,那么所有與之相綁定的組件停止之后它也將同時(shí)進(jìn)入停止?fàn)顟B(tài)。盡管Service與應(yīng)用程序的用戶界面并無(wú)關(guān)聯(lián),但隨Activity啟動(dòng)的Service會(huì)與之運(yùn)行在同一線程當(dāng)中。然而,如果大家的Service需要使用大量處理資源,那么我們最好為其創(chuàng)建一個(gè)獨(dú)立的運(yùn)行線程。請(qǐng)大家 點(diǎn)擊此處 查看更多來(lái)自Android開(kāi)發(fā)者指南中關(guān)于Service的說(shuō)明。
另一種組件Content Provider用于管理數(shù)據(jù)集。這里指的數(shù)據(jù)集既可以單純歸屬于我們的應(yīng)用程序,也可以與其它應(yīng)用所共享、能夠?qū)?shù)據(jù)進(jìn)行查詢及修改。如果大家為自己的應(yīng)用程序創(chuàng)建了一個(gè)用于管理數(shù)據(jù)的Content Provider,那么我們的UI組件(例如Activity)就能夠使用該Content Provider,通常是利用Content Resolver類來(lái)實(shí)現(xiàn)與數(shù)據(jù)的交互。當(dāng)被其它應(yīng)用程序使用時(shí),該Content Provider則通過(guò)標(biāo)準(zhǔn)方法來(lái)訪問(wèn)數(shù)據(jù)、從而與數(shù)據(jù)庫(kù)等結(jié)構(gòu)化數(shù)據(jù)集實(shí)現(xiàn)交互。
如果大家對(duì)于關(guān)系類數(shù)據(jù)庫(kù)已經(jīng)非常熟悉,那么應(yīng)該非常了解Content Provider所使用的數(shù)據(jù)訪問(wèn)方法。數(shù)據(jù)會(huì)被Content Provider提交給一系列包含行與列的表格,其中每行(或者每條記錄)中的列都包含一個(gè)單獨(dú)的數(shù)據(jù)值。因此,處理通過(guò)Content Provider返回的數(shù)據(jù)與處理數(shù)據(jù)庫(kù)查詢結(jié)果非常相似。
雖然有時(shí)候我們可能會(huì)創(chuàng)建一個(gè)專門(mén)的Content Provider程序,但在最初著手開(kāi)發(fā)自己的第一款應(yīng)用時(shí)、大家基本上還是會(huì)直接使用由其他開(kāi)發(fā)者或者Android系統(tǒng)本身所提供的Content Provider——例如設(shè)備日程表或者聯(lián)系人。Content Provider能夠定義客戶端應(yīng)用所需要的權(quán)限,從而實(shí)現(xiàn)內(nèi)容使用。為了在應(yīng)用程序當(dāng)中使用Content Provider,大家需要在Manifest當(dāng)中為其添加相應(yīng)的權(quán)限。
提示:如果大家只是需要一套應(yīng)用程序當(dāng)中的結(jié)構(gòu)化數(shù)據(jù)源,那么我們通常并不需要單獨(dú)創(chuàng)建Content Provider。大家可以創(chuàng)建一套只適用于我們應(yīng)用程序本身的SQLite數(shù)據(jù)庫(kù),而完全不需要使用Content Provider類。我們需要?jiǎng)?chuàng)建Content Provider的惟一情況在于,大家希望從我們的應(yīng)用程序當(dāng)中將結(jié)構(gòu)化數(shù)據(jù)復(fù)制到其它應(yīng)用處,或者大家希望使用搜索框架。
Android系統(tǒng)能夠發(fā)出多種應(yīng)用程序能夠響應(yīng)的廣播信息。大家也可以開(kāi)發(fā)出應(yīng)用程序來(lái)發(fā)出這些廣播,但這種可能性與監(jiān)聽(tīng)現(xiàn)有廣播相比要低得多,至少對(duì)我們的第一款應(yīng)用來(lái)說(shuō)是這樣。系統(tǒng)通知當(dāng)中包含關(guān)于設(shè)備硬件的各類信息,例如電池電量、屏幕關(guān)閉以及充電器是否接入插座等等。
為了接收來(lái)自Android系統(tǒng)的廣播通知,我們的應(yīng)用程序需要使用Broadcast Receiver。舉個(gè)典型的例子,電池電量工具會(huì)在電池電量發(fā)生實(shí)際變化時(shí)更新顯示結(jié)果。在這種情況下,大家可以將Service類與Broadcast Receiver配合使用,從而保證應(yīng)用程序始終在后臺(tái)監(jiān)聽(tīng)通知內(nèi)容。
Android系統(tǒng)將廣播通知稱為intent,它能夠被用于啟動(dòng)Activity。作為系統(tǒng)執(zhí)行的操作,intent可以實(shí)現(xiàn)Activity啟動(dòng)或者發(fā)出通知。要使用Broadcast Receiver,我們的應(yīng)用程序必須在Manifest中對(duì)其作出聲明;此外還有一套備選intent filter,用于指示我們想要接收的操作:
<receiver android:name=".YourReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_LOW" />
</intent-filter>
</receiver>
通過(guò)以上代碼,我們應(yīng)用中的Broadcast Receiver就能夠接收“battery low(電池電量低)”這一intent。請(qǐng)注意,我們無(wú)法通過(guò)在Manifest中聲明action這種方式接收全部系統(tǒng)通知。在某些情況下,大家必須完成注冊(cè)來(lái)實(shí)現(xiàn)通知接收,例如在Java當(dāng)中使用BATTERY_CHANGED action。
正如大家所見(jiàn),Android組件的設(shè)計(jì)初衷在于為不同應(yīng)用程序提供彼此之間的交互效果。正如廣播通知可用于系統(tǒng)之上的任何應(yīng)用,Android還提供其它一系列action、幫助我們?cè)趹?yīng)用程序中完成各類常見(jiàn)任務(wù)——例如撥打電話號(hào)碼。同樣,大家也可以使用由其他開(kāi)發(fā)人員所提供的功能,從而快速實(shí)現(xiàn)預(yù)定處理流程、節(jié)約代碼開(kāi)發(fā)量并幫助自己將更多精力集中在應(yīng)用程序的獨(dú)特之處上。當(dāng)我們啟動(dòng)一項(xiàng)intent時(shí),可以通過(guò)設(shè)置使其向啟動(dòng)中的Activity返回一個(gè)結(jié)果——即使所啟動(dòng)的intent并非我們應(yīng)用程序的組成部分。這就使我們的應(yīng)用能夠在要求操作完成之后繼續(xù)運(yùn)行。
其它值得關(guān)注的Android組件還包括fragment以及action bar。下面就讓我們簡(jiǎn)單對(duì)二者進(jìn)行探討:
Fragment
比起單純利用Activity以及布局配置來(lái)定義應(yīng)用程序中各個(gè)屏幕下的用戶界面,使用fragment的話效率可能會(huì)更高一些。在fragment的幫助下,大家可以將自己的用戶界面拆分為邏輯部分,甚至在應(yīng)用程序的多個(gè)屏幕之間重復(fù)使用同樣的部分。這樣一來(lái),我們不僅能夠節(jié)約大量花在實(shí)現(xiàn)同樣視覺(jué)/交互元素上的重復(fù)勞動(dòng),同時(shí)也實(shí)現(xiàn)了修改一點(diǎn)即完成對(duì)整款應(yīng)用變更的效果。Fragment在Android系統(tǒng)中屬于Activity中的組成部分,因此每個(gè)fragment都要與其所在的Activity生命周期相適應(yīng)。
Action Bar
在應(yīng)用程序開(kāi)發(fā)過(guò)程中,action bar也是我們經(jīng)常需要用到的關(guān)鍵性用戶界面元素。它的作用在于為我們的應(yīng)用程序提供足以作用于整套Android系統(tǒng)的用戶界面,這也使它成為該平臺(tái)用戶們最熟悉的元素。一般來(lái)說(shuō),action bar當(dāng)中所顯示的條目包括用戶在應(yīng)用程序當(dāng)中所處的位置以及應(yīng)用程序各個(gè)部分之間的導(dǎo)航系統(tǒng)。要在Activity當(dāng)中使用action bar,大家需要保證自己的類當(dāng)中包含ActionBarActivity類,并在Manifest當(dāng)中將AppCompat主題應(yīng)用在該Activity當(dāng)中。
具體使用哪一種Android類及組件取決于大家的應(yīng)用程序到底要執(zhí)行哪些任務(wù)。不過(guò)經(jīng)過(guò)文章的論述,相信應(yīng)該能夠幫助大家對(duì)類與組件的類型及數(shù)量有所了解,并根據(jù)實(shí)際情況作出正確選擇。對(duì)于特定特性或者功能來(lái)說(shuō),我們往往很難決定具體該使用哪款組件或者類,因此請(qǐng)大家在判斷之前確保自己對(duì)它們的作用擁有清晰的了解。在接下來(lái)的教程當(dāng)中,我們將探討Android示例代碼以及應(yīng)用程序的發(fā)布流程。
更多建議: