Read The Fucking Source Code
引言
- Context:最熟悉的陌生人谍夭。
-
全能小伙兒
:?jiǎn)?dòng)Activity黑滴、啟動(dòng)服務(wù)、注冊(cè)/發(fā)送廣播紧索、獲取ContentResolver袁辈、獲取類加載器、獲取資源珠漂、操作數(shù)據(jù)庫(kù)晚缩。
源碼版本(Android R — API 30)
整體概覽
Android 基礎(chǔ)組件 Context 概覽圖
1. 繼承關(guān)系圖
Android 基礎(chǔ)組件 Context 繼承關(guān)系圖
整體說(shuō)明
【上下文能力】:對(duì)外交互能力(上面提到的全能小伙兒
)尾膊。
- Context:上下文能力統(tǒng)籌定義。
- ContextWrapper:核心組件基類荞彼,關(guān)聯(lián)了ContextImpl冈敛,上下文能力執(zhí)行中轉(zhuǎn)端,最終交給ContextImpl執(zhí)行鸣皂。
- ContextImpl:上下文能力執(zhí)行代理端(真正執(zhí)行端)抓谴。
- ContextThemeWrapper:提供了主題能力,專門為Activity而生的寞缝。
- DecorContext:為DecorView而生癌压,擁有主題能力,為了更好的分類與解耦(相對(duì)Activity)第租。
- ReceiverRestrictedWrapper:為BroadcastReceiver而生措拇,閹割掉了綁定服務(wù)等能力。
2. 應(yīng)用組件 關(guān)聯(lián) Context
2.1 Application
Android 基礎(chǔ)組件 Context Application
2.2 Activity
Android 基礎(chǔ)組件 Context Activity
2.3 Service
Android 基礎(chǔ)組件 Context Service
2.4 BroadcastReceiver
Android 基礎(chǔ)組件 Context BroadcastReceiver
2.5 ContentProvider
Android 基礎(chǔ)組件 Context ContentProvider
3. 核心方法說(shuō)明
3.1 基礎(chǔ)類 核心方法說(shuō)明
Android 基礎(chǔ)組件 Context 基礎(chǔ)類核心方法說(shuō)明
3.2 應(yīng)用組件 核心方法說(shuō)明
Android 基礎(chǔ)組件 Context 四大組件類核心方法說(shuō)明
4. 小結(jié)
4.1 獨(dú)特的 Activity 啟動(dòng)
?Activity 的 Context 可以直接 startActivity
慎宾,其他的Context需要加上 FLAG_ACTIVITY_NEW_TASK
flags才能使用丐吓。為什么?由于 Activity 管理 UI視圖 的特殊性趟据,Activity 接管了本該由 ContextImpl 代理類來(lái)實(shí)現(xiàn)的功能券犁。所以同樣的方法,在 Activity 端的處理和 ContextImpl 的處理是不一致的汹碱。
4.2 獨(dú)特的 Activity 套娃
?Activity 的 getBaseContext
居然是 ContextThemeWrapper粘衬,如果我們?cè)?Activity中依然想使用 ContextImpl 的方法,舉例:那么直接 getBaseContext().startActivity
咳促,調(diào)用層次是:
- 獲取 Context 引用:
getBaseContext
-> ContextThemeWrapper稚新; - 繼承關(guān)系,直接調(diào)用父類:
ContextThemeWrapper.startActivity
->ContextWrapper.startActivity
跪腹; - 調(diào)用 ContextImpl(mBase) 代理:
ContextWrapper.startActivity
->mbase.startActivity
褂删。
?對(duì)比Application的 getBaseContext().startActivity
,調(diào)用層次是:
- 獲取 Context 引用:
getBaseContext
-> ContextImpl冲茸; - 調(diào)用 ContextImpl的
startActivity
屯阀。
4.3 被閹割的 BroadcastReceiver
?Receiver 的 Context 不可以執(zhí)行 bindService
操作。否則直接拋異常(源碼就不放了)轴术。
?Receiver 的 Context 執(zhí)行 registerReceiver
操作分情況處理难衰。只有當(dāng) receiver == null
用于獲取sticky廣播, 允許使用。
4.4 getApplicationContext 差異
- Application:
getApplicationContext()
就是自己 Application; - Activity/Service:
getApplication()
和getApplicationContext()
都是 Application; - BroadcastReceiver:在 onReceive 的過(guò)程逗栽,使用
getBaseContext().getApplicationContext()
獲取 Application; - ContentProvider:使用
getBaseContext().getApplicationContext()
獲取 Application(當(dāng)然有可能為空:Provider 在初始化不會(huì)創(chuàng)建 Application 對(duì)象盖袭,多個(gè) Apk 運(yùn)行在同一個(gè)進(jìn)程的情況下,第二個(gè) Apk 通過(guò) Provider 初始化,則 Context 為空)苍凛。
?