- Android和PHP開發(fā)最佳實(shí)踐(第2版)
- 黃雋實(shí)
- 648字
- 2018-12-31 20:29:03
2.4 Android系統(tǒng)四大組件
之前我們已經(jīng)學(xué)習(xí)了Android應(yīng)用框架的四大核心要點(diǎn),對Android的應(yīng)用框架有了一個(gè)總體性的了解,接下來我們要學(xué)習(xí)Android應(yīng)用程序中的四個(gè)重要組成部分,也就是我們一般所說的“應(yīng)用組件”。在前面講解四大核心要點(diǎn)的篇幅中,我們曾經(jīng)提到了控件(View控件)的概念,現(xiàn)在我們再來學(xué)習(xí)一下Android應(yīng)用框架中的組件的概念。那么何謂組件呢?顧名思義,組件當(dāng)然要比控件復(fù)雜,簡而言之,組件是用于工業(yè)化組裝的部件。要達(dá)到組件的標(biāo)準(zhǔn),必須符合三個(gè)要求,以下我們結(jié)合Android應(yīng)用框架討論如下。
1.有統(tǒng)一標(biāo)準(zhǔn)
這點(diǎn)應(yīng)該是形成組件的前提條件,試問,組件如果沒有標(biāo)準(zhǔn),如何組裝?在這點(diǎn)上,Android應(yīng)用框架中定義了很多標(biāo)準(zhǔn)接口,滿足了組件間的各種接口需求;換一種說法,整合Android系統(tǒng)都是按照接口規(guī)范設(shè)計(jì)出來的。
2.可獨(dú)立部署
組件應(yīng)該是獨(dú)立的,每個(gè)組件都有自成一套的功能體系,否則就沒有形成組件的必要。比如每個(gè)Activity都是可以獨(dú)立構(gòu)造的,使用Activity組件,我們可以完成一個(gè)包含許多復(fù)雜功能的界面;而使用Service,我們可以操作一個(gè)獨(dú)立的后臺(tái)進(jìn)程等。
3.可組裝整合
可組裝是組件最重要的特性,一個(gè)完整的Android應(yīng)用必然是若干個(gè)系統(tǒng)組件構(gòu)成的,這就要求組件必須是能組裝在一起的,至于如何組裝,我們會(huì)在后面的章節(jié)中結(jié)合實(shí)例進(jìn)行介紹。
通常來講,Android應(yīng)用框架中包含了四大組件:活動(dòng)(Activity)、服務(wù)(Service)、廣播接收器(Broadcast Receiver)和內(nèi)容提供者(Content Provider)。這四大組件除了具有前面所提到的三個(gè)特點(diǎn)之外,還有著相同的顯著特點(diǎn),那就是它們都可以在Android的基礎(chǔ)配置文件,即AndroidManifest.xml中進(jìn)行配置。下面我們就來學(xué)習(xí)Android系統(tǒng)四大組件的基本概念和使用方法。
2.4.1 活動(dòng)(Activity)
在2.3.1節(jié)中,我們已經(jīng)介紹了Android活動(dòng)(Activity)的生命周期以及基本行為,大家應(yīng)該對Activity的概念有了一定的了解。此外,Activity同時(shí)還是Android系統(tǒng)四大組件中的一員,因此,本節(jié)將著重介紹Activity作為組件的一般聲明方法。
說到Activity的聲明方法,我們必須先了解Android全局配置文件AndroidManifest.xml的基礎(chǔ)知識(shí)。每個(gè)Android應(yīng)用項(xiàng)目都會(huì)有自己的全局配置文件,該文件包含了應(yīng)用的系統(tǒng)常量、系統(tǒng)權(quán)限以及所含組件等配置信息。配置使用范例如代碼清單2-4所示。
代碼清單 2-4
<manifest ...> <application ...> <activity android:name="com.app.android.HelloActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:screenOrientation="landscape"> <intent-filter> ... </intent-filter> <intent-filter> ... </intent-filter> </activity> ... </application> <uses-permission .../> <uses-permission .../> ... </manifest>
從上述配置使用范例中,我們可以看到在AndroidManifest.xml配置文件范例的根元素<manifest/>下面有兩種標(biāo)簽,即<application/>和<uses-permission/>元素。前者是應(yīng)用配置的根元素,而后者則用于配置應(yīng)用的權(quán)限。這里順便說一下,每個(gè)Android應(yīng)用都必須事先聲明應(yīng)用需要的權(quán)限,比如是否需要網(wǎng)絡(luò)、是否需要使用攝像頭或者是否需要打開衛(wèi)星定位(GPS)等。而用戶在安裝該應(yīng)用之前,系統(tǒng)會(huì)先提示用戶是否允許該應(yīng)用使用這些權(quán)限,如果用戶覺得應(yīng)用不安全便可以選擇不安裝,這在一定程度上也提高了Android系統(tǒng)的安全性。
另外,我們還可以看到,在以上配制文件中的<application/>元素里面含有一個(gè)或者若干個(gè)<activity/>元素,這個(gè)就是我們需要重點(diǎn)了解的Activity標(biāo)簽了。首先,我們來看一下該標(biāo)簽內(nèi)部的一些常用的配置選項(xiàng)。
·android:name:表示該Activity對應(yīng)的類的名稱,在代碼清單2-4中,我們就定義了一個(gè)Activity,它的具體類包名就是“com.app.android.HelloActivity”。
·android:theme:表示Activity所使用的主題,在Android系統(tǒng)中是允許我們自定義主題的(這部分的內(nèi)容我們在后面章節(jié)的實(shí)例中會(huì)介紹到),在代碼清單2-4中,使用的是默認(rèn)主題“@android:style/Theme.NoTitleBar.Fullscreen”,也就是全屏模式。
·android:launchMode:Activity的行為模式,之前在2.3.4節(jié)中介紹過該標(biāo)簽的4種選項(xiàng),即與任務(wù)行為有關(guān)的Standard、singleTop、singleTask以及singleInstance。
·android:screenOrientation:表示屏幕的方向,在代碼清單2-4中,landscape表示的是該Activity是橫屏顯示的,如果改成portrait的話,則就變成豎屏顯示。
當(dāng)然,Activity標(biāo)簽可配置的選項(xiàng)遠(yuǎn)不止以上這些,更詳細(xì)的使用說明可以參考7.1.2節(jié)的內(nèi)容,使用范例可參考代碼清單7-11。此外,從上面的配制文件中我們還可以看到不止一個(gè)<intent-filter>元素。關(guān)于這點(diǎn),實(shí)際上,前面我們已經(jīng)介紹過消息過濾器的用法,如果大家有疑問的話,可以參考2.3.2節(jié)中與消息(Intent)相關(guān)的內(nèi)容。
另外,Activity在應(yīng)用開發(fā)中被用做控制界面的邏輯,也就是MVC中的Controller控制器,關(guān)于Android應(yīng)用中MVC的概念可參考5.2.3節(jié)中的內(nèi)容。開發(fā)者可以根據(jù)需要,在Activity的生命周期方法中添加不同的邏輯來控制對應(yīng)應(yīng)用界面的顯示、動(dòng)作和響應(yīng)等,而Activity類的具體用法和代碼示例我們可以在本書第7章的“微博實(shí)例”代碼中學(xué)習(xí)到。
2.4.2 服務(wù)(Service)
Android系統(tǒng)中的Service服務(wù)組件和Windows系統(tǒng)中的后臺(tái)服務(wù)有點(diǎn)類似,這個(gè)概念應(yīng)該很容易理解,比如,我們在退出某些聊天軟件之后還是可以接收到好友發(fā)來的消息,就是使用Android服務(wù)組件來實(shí)現(xiàn)的。此外,如果需要在應(yīng)用后臺(tái)運(yùn)行某些程序,Service服務(wù)組件也絕對是最佳的選擇。另外,值得注意的是,Service和之前的Activity一樣,也有自己的生命周期,但是,Service的生命周期相對簡單一些,如圖2-6所示。
從圖2-6中我們可以看出Android服務(wù)(Service)主要有以下兩種運(yùn)行模式。
·獨(dú)立運(yùn)行模式:我們一般通過“startService()”方法來啟動(dòng)一個(gè)獨(dú)立的服務(wù),在這種模式下,該服務(wù)不會(huì)返回任何信息給啟動(dòng)它的進(jìn)程,進(jìn)程的動(dòng)作結(jié)束后會(huì)自動(dòng)結(jié)束。比如,瀏覽器下載就屬于獨(dú)立服務(wù)。
·綁定運(yùn)行模式:與獨(dú)立服務(wù)不同,綁定服務(wù)是與啟動(dòng)它的應(yīng)用綁定在一起的,當(dāng)該應(yīng)用結(jié)束的時(shí)候,綁定服務(wù)也會(huì)停止。另外,這種服務(wù)可以和應(yīng)用中的其他模塊進(jìn)行信息交互,甚至進(jìn)行進(jìn)程通信(IPC)。

圖2-6 Service生命周期
與Activity類似,onCreate和onDestroy分別是Android服務(wù)創(chuàng)建和銷毀過程中的回調(diào)方法。與獨(dú)立運(yùn)行模式相比,綁定運(yùn)行模式中多出來onBind和onUnbind兩個(gè)函數(shù),分別是服務(wù)綁定和解綁過程的回調(diào)方法。在Android應(yīng)用開發(fā)的時(shí)候,我們通常會(huì)使用startService方法來開啟Service服務(wù)。另外,在應(yīng)用開發(fā)的時(shí)候千萬別忘了我們必須事先在全局配置文件中進(jìn)行如下聲明,如代碼清單2-5所示。
代碼清單 2-5
<application ...> <service android:name=".HelloService"/> <activity ...> ... </activity> </application>
理解Android服務(wù)(Service)時(shí)要特別注意,千萬不要盲目認(rèn)為服務(wù)是一個(gè)獨(dú)立的進(jìn)程或者線程。實(shí)際上,它和應(yīng)用程序的進(jìn)程之間存在著復(fù)雜的聯(lián)系,所以如果我們需要在Service中做一些耗時(shí)操作的話,必須新起一個(gè)線程并使用消息處理器Handler來處理消息。另外,Android服務(wù)的進(jìn)程間通信(IPC)功能還涉及AIDL(Android Interface Definition Language,Android接口定義語言),有興趣的話盡管去了解一下。關(guān)于Service的具體使用實(shí)例,大家可以先去看看Android SDK中API Demos里面的RemoteService實(shí)現(xiàn),本書后面的實(shí)例中我們也會(huì)穿插介紹。
小貼士:Handler是消息處理器,用于接受子線程的消息進(jìn)行處理并配合主線程更新UI界面,具體內(nèi)容可參考5.2.2節(jié)中界面基礎(chǔ)類BaseUi的相關(guān)內(nèi)容。
在Android系統(tǒng)中,Service服務(wù)類的使用方法比較簡單,執(zhí)行Service對象的start方法就可以開啟一個(gè)服務(wù)。實(shí)際上,第7章的“微博實(shí)例”中也有與Service服務(wù)相關(guān)的代碼實(shí)例,請參考7.5.4節(jié)。
2.4.3 廣播接收器(Broadcast Receiver)
廣播接收器(Broadcast Receiver)是Android系統(tǒng)的重要組件之一,可以用來接收其他應(yīng)用發(fā)出來的廣播,這樣不僅增強(qiáng)了Android系統(tǒng)的交互性,而且能在一定程度上提高用戶的操作體驗(yàn)。比如,你在把玩應(yīng)用或者游戲的同時(shí)也可以隨時(shí)接收一條短信或者一個(gè)電話,或者你在打開網(wǎng)頁的同時(shí)還可以接收短信驗(yàn)證碼等。
廣播接收器的使用也很簡單,和其他組件的步驟一樣:先聲明,再調(diào)用。代碼清單2-6就是一個(gè)聲明廣播接收器的例子。
代碼清單 2-6
<application ...> <receiver android:name=".HelloReceiver"> <intent-filter> <action android:name="com.app.basicreceiver.helloreceiver"/> </intent-filter> </receiver> <activity ...> ... </activity> </application>
這里我們定義了一個(gè)名為HelloReceiver的廣播接收器。這個(gè)類里面只有一個(gè)onReceive方法,里面我們可以定義需要的操作。使用的時(shí)候,我們可以在Activity中直接使用sendBroadcast方法來發(fā)送廣播消息,這樣HelloReceiver就會(huì)接收到我們發(fā)送的信息并進(jìn)行相應(yīng)的處理。這里需要注意的是,廣播接收器也是在應(yīng)用主線程里面的,所以我們不能在這里做一些耗時(shí)的操作,如果需要的話,可以新開線程來解決。發(fā)送廣播消息的范例如代碼清單2-7所示。
代碼清單 2-7
... Intent intent = new Intent("com.app.basicreceiver.hello"); sendBroadcast(intent); ...
而接收消息的使用范例,也就是廣播接收器類HelloReceiver的邏輯實(shí)現(xiàn),我們可以參考代碼清單2-8。
代碼清單 2-8
public class HelloReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Toast.makeText(context, "Receive Action : " + action, 1000).show(); } }
另外,我們需要了解,Android系統(tǒng)中的廣播消息是有等級(jí)的,可分為普通廣播(Normal Broadcasts)和有序廣播(Ordered Broadcasts)兩種。前者是完全異步的,可以被所有的接收者接收到,而且接收者無法終止廣播的傳播;而有序廣播則是按照接收者的優(yōu)先級(jí)別被依次接收到。優(yōu)先級(jí)別取決于intent-filter元素的android:priority屬性,數(shù)越大,優(yōu)先級(jí)越高。至于使用,我們通常會(huì)在onResume事件中通過registerReceiver進(jìn)行注冊,在onPause等事件中注銷,這種方式使其能夠在運(yùn)行期間保持對相關(guān)事件的關(guān)注。常見的廣播事件有:短信廣播、電量通知廣播等。
2.4.4 內(nèi)容提供者(Content Provider)
在Android應(yīng)用中,我們可以使用顯式消息(Explicit Intent)來直接訪問其他應(yīng)用的Activity,但是這僅限于Activity的范疇;如果需要使用其他應(yīng)用的數(shù)據(jù),還需要用到另外一種組件,這就是所謂的內(nèi)容提供者(Content Provider)。
顧名思義,內(nèi)容提供者就是Android應(yīng)用框架提供的應(yīng)用之間的數(shù)據(jù)提供和交換方案,它為所有的應(yīng)用開了一扇窗,應(yīng)用可以使用它對外提供數(shù)據(jù)。每個(gè)Content Provider類都使用URI(Universal Resource Identifier,通用資源標(biāo)識(shí)符)作為獨(dú)立的標(biāo)識(shí),格式如:content://xxx。其格式類似于REST,但是比REST更靈活,因?yàn)樵谡{(diào)用接口的時(shí)候還可以添加Projection、Selection、OrderBy等參數(shù),結(jié)果以Cursor的模式返回。Content Provider的聲明寫法非常簡單,示例可參考代碼清單2-9。
代碼清單 2-9
<application ...> <provider android:name="com.app.android.HelloProvider" android:authorities="com.app.android.HelloProvider"/> <activity ...> ... </activity> </application>
關(guān)于Content Provider的類實(shí)現(xiàn),我們只需要繼承ContentProvider接口并實(shí)現(xiàn)其中的抽象方法即可,這幾個(gè)方法有點(diǎn)類似于數(shù)據(jù)操作對象DAO的抽象方法,其中包括insert、delete、query和update這些常見的“增刪查改”的接口方法。對于具體的數(shù)據(jù)存儲(chǔ)來說,一般會(huì)使用Android的內(nèi)置數(shù)據(jù)庫SQLite,當(dāng)然也可以采用文件或者其他形式的混合數(shù)據(jù)來實(shí)現(xiàn)。關(guān)于Android系統(tǒng)中的數(shù)據(jù)存儲(chǔ)我們會(huì)在2.6節(jié)中介紹。
我們在使用上述四大組件的時(shí)候還需要注意的是:實(shí)際上,Service和Content Provider都可用于IPC(Inter-Process Communication,進(jìn)程間通信),也就是在多個(gè)應(yīng)用之間進(jìn)行數(shù)據(jù)交換。Service可以是異步的,而Content Provider則是同步的。在某些情況下,在設(shè)計(jì)的時(shí)候我們要考慮到性能問題。當(dāng)然,Android也提供了一個(gè)AsyncQueryHandler幫助異步訪問Content Provider。關(guān)于以上四大組件的具體使用,我們會(huì)在后面的章節(jié)中穿插介紹。
另外,與Content Provider配合使用的還有Content Resolver,即內(nèi)容處理器。前面也提到了Content Provider是以數(shù)據(jù)庫接口的方式將數(shù)據(jù)提供出去,那么Content Resolver也將采用類似的數(shù)據(jù)庫操作來從Content Provider中獲取數(shù)據(jù),而獲取數(shù)據(jù)就需要使用query接口。和Content Provider類似,Content Resolver也需要使用URI的方式來獲取對應(yīng)的內(nèi)容,其使用范例可參考7.3.2節(jié)中提到的HttpUtil類的相關(guān)代碼(代碼清單7-34)。
- Getting Started with React
- Android Studio Essentials
- PostgreSQL技術(shù)內(nèi)幕:事務(wù)處理深度探索
- AIRAndroid應(yīng)用開發(fā)實(shí)戰(zhàn)
- Building Mapping Applications with QGIS
- 深入淺出PostgreSQL
- Spring Boot企業(yè)級(jí)項(xiàng)目開發(fā)實(shí)戰(zhàn)
- C++新經(jīng)典
- iOS自動(dòng)化測試實(shí)戰(zhàn):基于Appium、Python與Pytest
- HTML+CSS+JavaScript網(wǎng)頁設(shè)計(jì)從入門到精通 (清華社"視頻大講堂"大系·網(wǎng)絡(luò)開發(fā)視頻大講堂)
- INSTANT Apache ServiceMix How-to
- Learning D
- 精通Rust(第2版)
- 程序員超強(qiáng)大腦
- Mastering Linux Kernel Development