初识Android应用程序的五大基本组件
5 Basic Components
1. ???????? Activity
2. ???????? Service
3. ???????? Broadcast Receiver
4. ???????? Content Provider
5. ???????? Intent
?
Activity —— 應用表示層( 基類 Activity )
?????? 應用程序中的每個屏幕都是通過繼承和擴展基類 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
?
Service —— 沒有可見的用戶界面,但能夠長時間運行于后臺( 基類 Service )
?????? 運行于應用程序進程的主線程中,因此 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
?
Broadcast Receiver —— 用戶接收廣播通知的組件( 基類 BroadcastReceiver )
?????? 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() 方法)
?
Content Provider —— 為解決應用程序間數據通信、共享的問題( 基類 ContentProvider )
?????? 在 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 將先啟動進程,同時確認被請求組件的實例是否存在,否則將創建一個新的組件實例。
?
Intent —— 連接組件的紐帶
?????? 以上 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 ,他們也需要相匹配才會通過測試。
總結
以上是生活随笔為你收集整理的初识Android应用程序的五大基本组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原神莫娜用什么武器好 莫娜武器推荐
- 下一篇: Android的启动过程