[android]android5大基礎元件深入分析

大搜車-自娛發表於2012-07-31
5 Basic Components
1. Activity
2. Service
3. Broadcast Receiver
4. Content Provider
5. Intent


[b]Activity —— 應用表示層(基類Activity)[/b]
應用程式中的每個螢幕都是通過繼承和擴充套件基類Activity來實現的。
同一應用中的每個Activity是相互獨立的。程式啟動後顯示的第一幅畫面是應用程式的第一個Activity(預設視窗),而後可以根據需要從這個Activity啟動另一個新的Activity。
Activity利用View來實現應用中的GUI(使用者直接通過GUI和應用程式做互動)。Activity視窗內的可見內容通過基類View提供。使用Activity.setContentView()方法設定當前Activity中的View物件。
l 每個View物件控制著視窗內的一個矩形空間;
l View是一種層次化結構,Parent View中的佈局屬性會被子View繼承;
l 位於View層次關係最底層的子View物件所代表的矩形空間就是跟使用者進行互動的地方

Activity狀態回撥:
l onCreate
l onStart
l onRestart
l onResume
l onPause
l onStop
l onDestroy


[b]Service —— 沒有可見的使用者介面,但能夠長時間執行於後臺(基類Service)[/b]
執行於應用程式程式的主執行緒中,因此Service不會阻塞其他元件和使用者介面。
Service是不能自己啟動的,必須通過Context物件(如一個Activity)呼叫startService或bindService方法來啟動(用這兩種方法啟動的Service的生命週期不同)。
1. 呼叫startService方法
a) 若Service沒有啟動,則首先會呼叫該Service的onCreate方法,然後再呼叫onStart方法。
b) 若Service已經啟動,則會直接呼叫onStart方法
c) 該方法啟動的Service,可以通過Context物件呼叫stopService來關閉,也可以通過Service自身呼叫stopSelf()或stopSelfResult()來關閉,關閉之前呼叫onDestory方法。
2. 呼叫bindService方法,使當前Context物件通過一個ServiceConnection的物件繫結到所指定的Service
a) 若Service沒有啟動,則首先會呼叫該Service的onCreate方法初始化啟動,然後呼叫Service的onBind方法初始化繫結。
b) 如果繫結Service的Context物件被銷燬時,被繫結的Service也會呼叫onUnbind 和 onDestroy方法停止執行
c) 注意: BroadcastReceiver是不能繫結服務的。
d) 一個繫結Service的Context物件還可以通過unbindService()來取消對服務的繫結。
e) 取消時,Service會呼叫unbind方法,若Service是通過bindService來啟動的,還會呼叫onDestroy方法來停止服務。
       Service狀態回撥:
l onCreate
l onStart
l onBind
l onRebind
l onUnbind
l onDestroy


[b]Broadcast Receiver —— 使用者接收廣播通知的元件(基類BroadcastReceiver)[/b]
Android中的廣播要麼來自於系統,要麼來自普通應用程式。
很多事件都可能導致系統廣播,如手機所在時區發生變化,電池電量低,使用者改變系統語言設定等。
來自普通應用程式,如一個應用程式通知其他應用程式某些資料已經下載完畢。
為了響應不同的事件通知,應用程式可以註冊不同的Broadcast Receiver。所有的Broadcast Receiver都繼承自基類BroadcastReceiver。
BroadcastReceiver自身並不實現圖形使用者介面,但是當它收到某個通知後,BroadcastReceiver可以啟動Activity作為響應,或者通過NotificationMananger提醒使用者。
BroadcastReceiver是對傳送出來的Broadcast進行過濾接收並響應的一類元件。

傳送Broadcast資訊
1. 把要傳送的資訊和用於過濾得資訊(如Action、Category)裝入一個Intent物件
2. 呼叫Context.sendBroadcast()、sendOrderBroadcast()、sendStickyBroadcast()方法,廣播該Intent物件
3. 使用sendBroadcast() 或sendStickyBroadcast()方法發出去的Intent,所有滿足條件的BroadcastReceiver都會隨機地執行其onReceive()方法;
4. 而sendOrderBroadcast()發出去的Intent,會根據BroadcastReceiver註冊時IntentFilter設定的優先順序的順序來執行,相同優先順序的BroadcastReceiver則是隨機執行
5. sendStickyBroadcast()方法主要的不同是,Intent在傳送後一直存在,並且在以後呼叫registerReceiver()註冊相匹配的Intent時會把這個Intent直接返回。
6. 若在使用sendBroadcast()方法時指定了接收的許可權,這隻有在AndroidManifest.xml中用<uses-permission>標籤宣告瞭擁有此許可權的BroadcastReceiver才會有可能接收到傳送來Broadcast。
7. 若在註冊BroadcastReciever時,指定了可接收的Broadcast的許可權,則只有在包內的AndroidManifest.xml中用<uses-permission>標籤宣告瞭,擁有此許可權的Context物件所傳送的Broadcast才有可能被這個BroadcastReceiver所接收。
接收Broadcast訊息
1. 繼承BroadcastReceiver 類,並實現onReceive方法
2. 註冊Broadcast Receiver(有2種方法:一種方法是,靜態地在AndroidManifest.xml中用<receiver>標籤宣告,並在標籤內用<intent-filter>標籤設定過濾器; 另一種方法,動態地在程式碼中先定義並設定好一個IntentFilter物件,然後再需要註冊的地方呼叫Context.registerReceiver()方法) (取消註冊時,呼叫Context.unregisterReceiver()方法)

[b]Content Provider —— 為解決應用程式間資料通訊、共享的問題(基類ContentProvider)[/b]
在Android中,每個應用程式都是用自己的使用者ID並在自己的程式中執行。這樣的好處是,可以有效地保護系統及應用程式,避免被其他不正常德應用程式所影響,每個程式都擁有獨立的程式地址空間和虛擬空間。
Content Provider可以將應用程式特定的資料提供給另一個應用程式使用。其資料儲存方式可以是Android檔案系統、SQLite資料庫或者其他合理的方式。
當資料需要在應用程式間共享時,我們就可以利用ContentProvider為資料定義一個URI。之後,其他應用程式對資料進行查詢或者修改時,只需要從當前上下文物件獲得一個ContentResolver, 然後傳入響應的URI就可以了。
Content Provider 繼承自基類ContentProvider,並且實現了一組標準介面。通過這組介面,其他應用程式能對資料進行讀寫和儲存。然而,需要使用資料的應用程式並不是直接呼叫這組方法,而是通過呼叫ContentResolver物件的方法來完成。ContentResolver物件可以與任意ContentProvider通訊。
要為當前應用程式的私有資料定義URI,就需要專門定義一個繼承自ContentProvider的類,然後根據不同的操作呼叫的方法去實現這些方法的功能。
ContentResolver類為應用程式提供了接入Content機制的方法。要構造一個ContentResolver物件可以為構造方法ContentResolver(Context context)傳入一個Context物件,也可以直接通過Context物件呼叫getContentResolver()方法獲得 —— 有的ContentResolver物件後,就可以通過呼叫其query()、insert()、update()等方法來對資料進行操作了。

一旦需要以上4種Android應用程式基本元件完成請求,Android會首先確認該元件所在程式是否執行,如果沒有執行,Android將先啟動程式,同時確認被請求元件的例項是否存在,否則將建立一個新的元件例項。

[b]Intent —— 連線元件的紐帶[/b]
以上4種基本元件中,除了Content Provider是通過Content Resolver啟用外,其他3種元件Activity、Service和Broadcast Receiver都是由Intent非同步訊息啟用的。
Intent在不同的元件之間傳遞訊息,將一個元件的請求意圖傳給另一個元件。因此,Intent是包含具體請求資訊的物件。
針對不同的元件,Intent所包含的訊息內容有所不同,且不同元件的啟用方式也不同, 且不同型別元件有傳遞Intent的不同方式。
Intent是一種執行時繫結(runtime binding)機制,它能夠在程式執行的過程中連線兩個不同的元件。通過Intent,你的程式可以向Android表到某種請求或者意願,Android會根據意願的內容選擇適當的元件來處理請求。
l 啟用一個新的Activity,或者讓一個現有的Activity執行一個新的操作,可以通過呼叫如下兩種方法(這兩彙總方法需要傳入的Intent引數稱為Activity Action Intent):
1. Context.startActivity()
2. Activity.startActivityForResult()
l 啟動一個新的服務,或者向一個已有的服務傳遞新的指令,可以呼叫如下兩種方法:
1. Context.startService()
2. Context.bindService()
l 傳送廣播Intent(所有已註冊的擁有與之相匹配IntenFilter的BroadcastReceiv就會被啟用),可以呼叫如下三種方法:
1. Context.sendBroadcast()
2. Context.sendOrderBroadcast()
3. Context.sendStickBroadcast()
Intent一旦發出,Android都會準確找到相匹配的一個或多個Activity、Service或BroadcastReceiver作響應。所以,不同型別的Intent訊息不會出現重疊,BroadcastIntent訊息只會傳送給BroadcastReceiver,而絕不可能傳送給Activity或Server。有startActivity()傳遞的訊息也只可能傳送給Activity,由startService()傳遞的Intent只可能傳送給Service。

Intent物件抽象地描述了執行操作,Intent的主要組成部分;
1. 目標元件名稱。[可選項]
a) 元件名稱是一個ComponentName物件,是目標元件類名和目標元件所在應用程式包的組合
b) 元件中的包名不一定要和manifes檔案中包名完全匹配
c) 如果Intent訊息中指明瞭目標元件的名稱,這就是一個顯示訊息,Intent會傳遞給指明的元件。
d) 如果目標元件名稱並沒有指定,Android則通過Intent內的其他資訊和已註冊的IntentFilter的比較來選擇合適的目標元件
2. Action [隱式比較]
a) 描述Intent所觸發動作的名字字串。
b) 理論上Action可以為任何字串,而與Android系統應用有關的Action字串以靜態字串常量的形式定義在了Intent類中。
3. Data [隱式比較]
a) 描述Intent要操作的的資料的URI和資料型別。
b) 正確設定Intent的資料對於Android尋找系統中匹配Intent請求的元件很重要。
4. Category [隱式比較]
a) 是對被請求元件的額外描述資訊。
b) Android也在Intent類中定義了一組靜態字串常量表示Intent不同的類別。
5. Extra
a) 當我們使用Intent連線不同元件時,有時需要在Intent中附加額外的資訊,以便將資料傳遞給目標Activity。
b) Extra用鍵值對結構儲存在Intent物件當中,Intent物件通過呼叫方法putExtras() 和 getExtras()來儲存和獲取Extra
c) Extra是以Bundle物件的形式來儲存的,Bundle物件提供了一系列put和get方法來設定、提取相應鍵值資訊。
d) 在Intent類中同樣為Android系統應用的一些Extra的鍵值定義了靜態字串常量。
6. Flag

決定Intent目標元件的因素:
n 在顯式Intent訊息中,決定目標元件的唯一要素就是元件名稱(不用再定義其他Intent內容)
n 而隱式Intent訊息中,由於沒有目標元件名稱,所以必須由Android系統幫助應用程式尋找與Intent請求意圖最匹配的元件。
n 隱式Intent訊息中目標元件具體選擇方法是:android將Intent的請求內容和一個叫做IntentFilter的過濾器比較,IntentFilter中包含系統中所有可能的待選元件。如果IntentFilter中某一個元件匹配隱式Intent請求內容,那麼Android就選擇該元件作為該隱式Intent的目標元件。

IntenFilter
應用程式的元件為了告訴Android自己能響應、處理哪些隱式Intent請求,可以宣告一個甚至多個IntentFilter。
每個IntentFilter描述該元件所能響應Intent請求的能力 —— 元件希望接收什麼型別的請求行為,什麼型別的請求資料。
隱式Intent和IntentFilter進行比較時的三要素:Action、Data、Category。
一個隱式Intent請求要能夠傳遞給目標元件,必需通過以上三個方面的檢查。如果任何一方面不匹配,Android都不會將該隱式Intent傳遞給目標元件。
<intent-filter>
<action android:name=””/>
<category android:name=””/>
<data android:type=”” android:scheme=”” android:authority=”” android:path=””/>
</intent-filter>
1. 動作測試
a) 一條 <intent-filter> 中至少應該包含一個<action>, 否則任何Intent請求都不能和該<intent-filter> 匹配。
b) 如果IntentFilter 中沒有包含任何Actino型別,那麼無論什麼Intent請求都無法和這條IntentFilter匹配。
c) 如果Intent請求中沒有設定Action型別,那麼只要IntentFilter中包含有Action型別,這個Intent請求將順利通過IntentFilter的測試。
2. 類別測試
a) 只有當Intent請求中所有的Category與元件中的某一個IntentFilter的category完全匹配,才會讓該Intent請求通過測試,IntentFilter中的多餘category宣告並不會導致匹配失敗。
b) 一個沒有指定任何類別的IntentFilter僅僅只會匹配沒有設定類別的Intent請求。
3. 資料測試
a) <data>元素指定了希望接受的Intent請求的資料URI和資料型別:URI被分成三部分類進行匹配,scheme、authority和 path.
b) 使用 setData設定的Intent請求的URI資料型別和scheme,必須與IntentFilter中指定的一致
若IntentFilter中還指定了authority或path,他們也需要相匹配才會通過測試。


轉載至:http://blog.csdn.net/crazyjeff_liu/article/details/5545806

相關文章