進階之路 | 奇妙的四大元件之旅
前言
本文已經收錄到我的
Github
個人部落格,歡迎大佬們光臨寒舍:我的GIthub部落格
學習清單:
Activity
的工作過程Service
的工作過程
Service
的啟動過程Service
的繫結過程
BroadcastReceiver
的工作過程
BroadcastReceiver
的註冊過程BroadcastReceiver
的傳送和接收過程
ContentProvider
的工作過程
一.為什麼要學習四大元件?
何為“四大”:
Activity
Service
BroadcastReceiver
ContentProvider
談到四大元件,相信在座各位都再熟悉不過了,光聞其名,未見其聲,“四大”二字一出,足見其在安卓系統中的地位,可謂是安卓界的F4
其地位之崇高,在某種程度上也可以體現他的重要性,所以說,光會使用四大元件還是不能體現我們對他的重視(ai hu)的,我們還要分析其工作過程,能夠更好地理解系統內部的執行機制,從而加深對Android
體系結構的認識;同時,四大元件還是面試必問的知識點之一。
綜上,掌握好四大元件相關的知識,對於一個Android
開發者來說是非常重要的!
以下內容緊張赤雞,請繫好保險帶,我們要開車(hu you)了。— No picture,say a J8!
二.核心知識點歸納
2.1 概述
2.1.1 Activity
型別:展示型元件
作用:展示一個介面並和使用者互動
使用:
A.需要在
AndroidManifest
B.需要藉助
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);
- 四種啟動模式:
standard
:標準模式singleTop
:棧頂複用模式singleTask
:棧內複用模式singleInstance
:單例項模式想了解啟動模式的讀者,可以看下筆者寫的一篇文章:進階之路 | 奇妙的Activity之旅中的
2.2
部分
- 通過
finish()
結束一個Activity
2.1.2 Service
型別:計算型元件
作用:在後臺執行一系列計算任務,耗時的後臺計算建議在單獨的執行緒中執行
使用:
A.需要在
AndroidManifest
中註冊B.需要藉助
Intent
啟動:Intent intent = new Intent(xxx.this, xxx.class); startService(intent);
C.兩種執行狀態:
- 啟動狀態:通過
startService()
- 繫結狀態:通過
bindService()
D.停止方式:unBindService();stopService();
2.1.3 BroadcastReceiver
- 型別:訊息型元件
- 作用:在不同的元件乃至不同的應用之間傳遞訊息
- 使用:
兩種註冊方式:
A.動態註冊:通過
Context.registerReceiver()
&Context.unRegisterReceiver()
,必須要啟動應用才能註冊並接收廣播。B.靜態註冊:在
AndroidManifest
檔案中註冊,不需要啟動應用即可接收廣播。需要藉助
Intent
傳送廣播:Intent intent = new Intent("xxx"); sendBroadcast(intent);
四種廣播型別:
A.普通廣播
B.有序廣播
C.本地廣播
D.粘性廣播
- 沒有停止概念
2.1.4 ContentProvider
- 型別:共享型元件
- 作用:向其他元件乃至其他應用共享資料(安卓
IPC
的一種方式) - 使用:
- 需要在
AndroidManifest
中註冊- 無需藉助
Intent
啟動四種操作:注意需要處理好執行緒同步(因為這些操作執行在
Binder
執行緒)A.
insert()
:新增資料B.
update()
:更新資料C.
delete()
:刪除資料D.
query()
:查詢資料
- 無需手動停止
想詳細瞭解
IPC
機制的讀者,可以看下筆者寫的一篇文章:進階之路 | 奇妙的 IPC 之旅
2.2 工作過程
差不多該進入今天的主題了,為了逼格,為了高薪,大夥往前衝!
2.2.1 Activity
Activity
啟動過程流程圖:
一眼看上去有點暈暈的,牆裂建議配合原始碼一起服用,效果極佳,筆者推薦一篇文章:圖解Activity啟動流程,進階高階
Q1:結論:
ActivityManagerService
、ApplicationThread
都是Binder
Application
的建立也是通過Instrumentation
來完成的,這個過程和Activity
物件一樣,都是通過類載入器來實現的Activity
的啟動過程最終回到ApplicationThread
中,通過ApplicationThread.scheduleLaunchActivity()
將啟動Activity
的訊息傳送並交由Handler H
處理。Handler H
對訊息的處理會呼叫handleLaunchActivity()
->performLaunchActivity()
得以最終完成Activity的建立和啟動。
Q2:重點類:
Instrumentation
:
instrumentation
是Android
系統裡面的一套控制方法或者”鉤子“。 這些鉤子可以在正常的生命週期(正常是由作業系統控制的)之外控制Android
控制元件的執行;它們同時可以控制Android
如何載入應用程式。
ActivityManagerService「AMS」
:
AMS
是系統的引導服務,應用程序的啟動、切換和排程、四大元件的啟動和管理都需要AMS
的支援。
ActivityStackSupervisor
:
ActivityStackSupervisor
在AMS
中的構造方法中被建立。
AMS
通過操作ActivityStackSupervisor
來管理Activity
ActivityStack
:
ActivityStack
從名稱來看是跟棧相關的類,其實它是一個管理類,用來管理系統所有Activity
的各種狀態- 它由
ActivityStackSupervisor
來進行管理的
ApplicationThread
:
ActivityThread
的私有內部類,也是一個Binder
物件- 在此處它是作為
IApplicationThread
物件的Server
端,等待Client
端的請求然後進行處理,最大的Client
就是AMS
2.2.2 Service
原始碼流程分析:Service的工作過程
1.啟動過程:
2.繫結過程:
結論:
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()
去完成。
2.2.3 BroadcastReceiver
原始碼流程分析:BroadcastReceiver 的工作過程分析
1.註冊
四大元件的靜態註冊都是在應用安裝時由
PackageManagerService(PMS)
解析註冊,當動態註冊BroadcastReceiver
時流程為:
2.傳送和接收
結論:
- 動態註冊廣播最終會跨程序交給
AMS
,並把遠端Receiver
( 實際上傳的是IIntentReceiver
,是個Binder
物件)和遠端IntentFilter
儲存起來,完成註冊任務 - 傳送廣播時,系統為intent添加了兩個標記位:
FLAG_EXCLUDE_STOPPED_PACKAGES
:廣播不會發送給已經停止的APP
(系統為所有廣播預設新增該標記)FLAG_INCLUDE_STOPPED_PACKAGES
:廣播也會發送到已經停止的APP
(兩個標記共存時,以該標記為準)
- 最終在
ReceiverDispatcher .performReceive ()
裡回調了Receiver
的onReceive()
,使得廣播得以接收並處理
Q2:實現原理:
從實現原理看上,廣播使用了觀察者模式,基於訊息的釋出/訂閱事件模型
具體實現流程要點粗略概括如下:
- 廣播接收者
BroadcastReceiver
通過Binder
機制向AMS
進行註冊 - 廣播發送者通過
Binder
機制向AMS
傳送廣播 AMS
查詢符合相應條件(IntentFilter
/Permission
等)的BroadcastReceiver
,將廣播發送到BroadcastReceiver
(一般情況下是Activity
)相應的訊息迴圈佇列中- 訊息迴圈執行拿到此廣播,回撥
BroadcastReceiver
中的onReceive()
方法
2.2.4 ContentProvider
1.啟動流程總概
- 啟動的入口為
ActivityThread.main()
:建立ActivityThread
例項並建立主執行緒訊息佇列 ActivityThread.attach()
:遠端呼叫AMS.attachApplication()
並提供ApplicationThread
用於和AMS
的通訊AMS.attachApplication()
:通過ActivityThread.bindApplication()
方法和Handler H
來調回ActivityThread.handleBindApplication()
ActivityThread.handleBindApplication()
:先建立Application
、再載入ContentProvider
、最後回撥Application.onCreate()
2.Query
過程流程
insert()
、delete()
和update()
的實現原理和query()
類似,限於篇幅,這裡不展開,感興趣的讀者可以主動去探究原始碼流程分析:ContentProvider的工作過程
結論:
ContentProvider
的multiprocess
屬性:ContentProvider
是否是單例,一般用單例訪問
ContentProvider
需要ContentResolver
,其真正實現類是ApplicationContentResolver
。當ContentProvider
所在程序未啟動時,第一次訪問它會觸發ContentProvider
的建立以及程序啟動當
ContentProvider
所在的程序啟動時,會同時被啟動並被髮布到AMS
中
注意:
ContentProvider.onCreate()
要先於Application.onCreate()
執行
- 同樣的,最終通過
ActivityThread.handleBindApplication()
完成ContentProvider
的建立。
三.課堂小測試
恭喜你!已經看完了前面的文章,相信你對
四大元件
已經有一定深度的瞭解,下面,進行一下課堂小測試,驗證一下自己的學習成果吧!
Q1:為什麼要使用ContentProvider
?它和SQL
在實現上有什麼區別?
ContentProvider
遮蔽了資料儲存的細節,內部實現透明化,使用者只需關心URI
即可(是否匹配)ContentProvider
能實現不同APP
的資料共享,SQL
只能是自己程式才能訪問ContentProvider
還能增刪本地的檔案,XML
等資訊
Q2:Android
引入四大元件的用意
這個問題在筆者剛開始學習
Android
的時候就一直困惑,直到看了一篇Google Android 團隊:Dianne Hackborn發表在Google+
上的一篇post
的譯文
見解:Google Android Framework
團隊決定,不要讓一個明確的Main
方法作為APP
的入口,因為需要讓系統對APP
怎樣執行有更多的控制權,在該系統中,使用者永遠不需要考慮開啟和停止一個APP
,而把這些事交給系統去管理。所以他們設計了四大元件以作為APP
功能的載體和入口:
Activity
一個
APP
與使用者互動的入口BroadcastReceiver
- 一種讓系統在正常的使用者流(
user flow
)之外,傳遞事件給APP
的機制。- 最重要的是,因為這是另一個被精心定義的
APP
的入口,即使APP
當前並不在執行,系統也可以將Broadcasts
傳遞給APP
。
Service
當
APP
由於各種各樣的原因需要在後臺執行時,Service
就是一個這樣的入口
ContentProvider
- 人們通常會將它當作對資料庫的抽象,因為有許多的
API
和支援庫就是這樣使用ContentProvider
的- 但是從系統設計的角度,這並不是
ContentProvider
的初衷。對於系統來說,ContentProvider
實際上是一個入口,用於獲取一個APP
內部的公開的被命名的資料項(data items
),每個資料項都被一個URI scheme
所標識。
如果文章對您有一點幫助的話,希望您能點一下贊,您的點贊,是我前進的動力
本文參考連結:
- 《Android 開發藝術探索》
- 進階之路 | 奇妙的Activity之旅
- 進階之路 | 奇妙的 IPC 之旅
- 圖解Activity啟動流程,進階高階
- Service的工作過程
- BroadcastReceiver 的工作過程分析
- ContentProvider的工作過程
- 關於Android四大元件最權威最深刻最準確的解讀
- Android開發藝術探索讀書筆記(三)
- 要點提煉|開發藝術之四大元件
- 「Android」四大元件,你真的都掌握了?
- "ContentProvider和資料庫"的區別和聯絡專題