提到四大元件大家肯定再熟悉不過了,本篇側重於對四大元件工作過程進行分析:
- 概述
- 工作過程
- Activity
- Service
- BroadcastReceiver
- ContentProvider
1.概述
a.Activity
- 型別:展示型元件。
- 作用:展示一個介面並和使用者互動。
- 使用:
- 需要在AndroidManifest中註冊。
- 需要藉助Intent啟動,兩種方式:
- 顯示Intent:
Intent intent=new Intent(xxx.this,xxx.class); startActivity(intent);
- 隱式Intent:
Intent intent=new Intent(); intent.setAction(xxx); intent.addCategory(xxx); startActivity(intent);
- 顯示Intent:
- 四種啟動模式:
- standard:標準模式
- singleTop:棧頂複用模式
- singleTask:棧內複用模式
- singleInstance:單例項模式
- 對使用者而言是可見的。
- 通過
finish()
結束一個Activity。
相關基礎:入門之Activity篇、開發藝術之Activity
b.Service
- 型別:計算型元件。
- 作用:在後臺執行一系列計算任務,耗時的後臺計算建議在單獨的執行緒中執行。
- 使用:
- 需要在AndroidManifest中註冊。
- 需要藉助Intent啟動:
Intent intent = new Intent(xxx.this, xxx.class); startService(intent);
- 兩種執行狀態:
- 啟動狀態:通過
startService()
- 繫結狀態:通過
bindService()
- 啟動狀態:通過
- 使用者無法感知。
- 通過
unBindService()
和stopService()
完全停止一個Service。
相關基礎:入門之Service篇
c.BroadcastReceiver
- 型別:訊息型元件。
- 作用:在不同的元件乃至不同的應用之間傳遞訊息。
- 使用:
- 兩種註冊方式:
- 動態註冊:通過
Context.registerReceiver()
&Context.unRegisterReceiver()
,必須要應用啟動才能註冊並接收廣播。 - 靜態註冊:在AndroidManifest檔案中註冊,不需要啟動應用即可接收廣播。
- 動態註冊:通過
- 需要藉助Intent傳送廣播:
Intent intent = new Intent("xxx"); sendBroadcast(intent);
- 四種廣播型別:
- 普通廣播
- 有序廣播
- 本地廣播
- 粘性廣播
- 使用者無法感知。
- 沒有停止概念。
- 兩種註冊方式:
d.ContentProvider
- 型別:共享型元件。
- 作用:向其他元件乃至其他應用共享資料。
- 使用:
- 需要在AndroidManifest中註冊。
- 無需藉助Intent啟動。
- 四種操作:注意需要處理好執行緒同步
insert()
:新增資料update()
:更新資料delete()
:刪除資料query()
:查詢資料
- 使用者無法感知。
- 無需手動停止。
相關基礎:入門之ContentProvider篇、IPC方式之ContentProvider
考考自己:android四大元件的執行狀態
二.工作過程
由於相關原始碼非常多,這裡借用@amurocrash的UML圖來提煉流程更為直觀,另附相關原始碼分析的文章供大家詳細瞭解。
a.Activity
Activity啟動過程流程圖:
結論:
- ActivityManagerService、ApplicationThread都是Binder。
- Application的建立也是通過Instrumentation來完成的,這個過程和Activity物件一樣,都是通過類載入器來實現的。
- Activity的啟動過程最終回到ApplicationThread中,通過
ApplicationThread.scheduleLaunchActivity()
將啟動Activity的訊息傳送並交由Handler H處理。 - Handler H對訊息的處理會呼叫
handleLaunchActivity()
->performLaunchActivity()
得以最終完成Activity的建立和啟動。
原始碼分析:Activity的工作過程
b.Service
- Service啟動過程流程圖:
- Service繫結過程流程圖:
結論:
- ContextImpl是Context的具體實現,通過
Activity.attach()
和Activity建立關聯。Activity.attach()
中還會完成Window的建立並和Activity&Window的關聯,由此事件可傳遞給Window。 - ActivityServices是一個輔助ActivityManagerService(AMS)進行Service管理的類,包括Service的啟動、繫結和停止。
- 和Activity類似的,Service的啟動/繫結過程最終回到ApplicationThread中,通過
ActivityThread.handleCreateService()
/ActivityThread.handleBindService
完成Service的啟動/繫結,注意繫結Service的後續還必須 告知客戶端已經成功連線Service 的這一流程,由ActivityManagerService.publishService()
去完成。
原始碼分析: Service的工作過程
c.ContentProvider
- ContentProvider啟動過程流程圖:
- 啟動的入口為
ActivityThread.main()
:建立ActivityThread例項並建立主執行緒訊息佇列;- ->
ActivityThread.attach()
:遠端呼叫AMS.attachApplication()
並提供ApplicationThread用於和AMS的通訊;- ->
AMS.attachApplication()
:通過ActivityThread.bindApplication()
方法和Handler H來調回ActivityThread.handleBindApplication()
;- ->
ActivityThread.handleBindApplication()
:先建立Application、再載入ContentProvider、最後回撥Application.onCreate()
。
圖片來源:四大元件的工作過程
- Query過程流程圖:
insert()
、delete()
和update()
類似,這裡不展開
結論:
- ContentProvider的multiprocess屬性:ContentProvider是否是單例,一般用單例。
- 訪問ContentProvider需要ContentResolver,其真正實現類是ApplicationContentResolver。當ContentProvider所在程式未啟動時,第一次訪問它會觸發ContentProvider的建立以及程式啟動。
- 當ContentProvider所在的程式啟動時,會同時被啟動並被髮布到AMS中。注意:
ContentProvider.onCreate()
要先於Application.onCreate()
執行。 - 同樣的,最終通過
ActivityThread.handleBindApplication()
完成ContentProvider的建立。
原始碼分析: ContentProvider的工作過程
d.BroadcastReceiver
- 四大元件的靜態註冊都是在應用安裝時由PackageManagerService(PMS)解析註冊,當動態註冊Service時流程為:
- 廣播傳送和接收過程流程圖:
結論:
- 動態註冊廣播最終會跨程式交給AMS,並把遠端Receiver( 實際上傳的是IIntentReceiver,是個Binder )物件和遠端IntentFilter儲存起來,完成註冊任務。
- 傳送廣播時,系統未intent新增了兩個標記位:
- FLAG_INCLUDE_STOPPED_PACKAGES :廣播也會傳送到已經停止的APP(兩個標記共存時,以該標記為準)
- FLAG_EXCLUDE_STOPPED_PACKAGES :廣播不會傳送給已經停止的APP(系統為所有廣播預設新增該標記)
- 最終在
ReceiverDispatcher .performReceive ()
裡回撥了Receiver 的onReceive()
,使得廣播得以接收並處理。
原始碼分析: BroadcastReceiver 的工作過程
希望這篇文章對你有幫助~