Android Context

Read The Fucking Source Code

引言
  • Context:最熟悉的陌生人。
  • 全能小伙兒:?jiǎn)?dòng)Activity、啟動(dòng)服務(wù)、注冊(cè)/發(fā)送廣播、獲取ContentResolver、獲取類加載器、獲取資源、操作數(shù)據(jù)庫。

源碼版本(Android R — API 30)

整體概覽

Android 基礎(chǔ)組件 Context 概覽圖

1. 繼承關(guān)系圖

Android 基礎(chǔ)組件 Context 繼承關(guān)系圖

整體說明

【上下文能力】:對(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. 核心方法說明

3.1 基礎(chǔ)類 核心方法說明

Android 基礎(chǔ)組件 Context 基礎(chǔ)類核心方法說明

3.2 應(yīng)用組件 核心方法說明

Android 基礎(chǔ)組件 Context 四大組件類核心方法說明

4. 小結(jié)

4.1 獨(dú)特的 Activity 啟動(dòng)

?Activity 的 Context 可以直接 startActivity,其他的Context需要加上 FLAG_ACTIVITY_NEW_TASK flags才能使用。為什么?由于 Activity 管理 UI視圖 的特殊性,Activity 接管了本該由 ContextImpl 代理類來實(shí)現(xiàn)的功能。所以同樣的方法,在 Activity 端的處理和 ContextImpl 的處理是不一致的。

4.2 獨(dú)特的 Activity 套娃

?Activity 的 getBaseContext 居然是 ContextThemeWrapper,如果我們?cè)?Activity中依然想使用 ContextImpl 的方法,舉例:那么直接 getBaseContext().startActivity,調(diào)用層次是:

  1. 獲取 Context 引用:getBaseContext -> ContextThemeWrapper;
  2. 繼承關(guān)系,直接調(diào)用父類:ContextThemeWrapper.startActivity -> ContextWrapper.startActivity;
  3. 調(diào)用 ContextImpl(mBase) 代理:ContextWrapper.startActivity -> mbase.startActivity。

?對(duì)比Application的 getBaseContext().startActivity ,調(diào)用層次是:

  1. 獲取 Context 引用:getBaseContext -> ContextImpl;
  2. 調(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 的過程,使用 getBaseContext().getApplicationContext() 獲取 Application;
  • ContentProvider:使用 getBaseContext().getApplicationContext() 獲取 Application(當(dāng)然有可能為空:Provider 在初始化不會(huì)創(chuàng)建 Application 對(duì)象,多個(gè) Apk 運(yùn)行在同一個(gè)進(jìn)程的情況下,第二個(gè) Apk 通過 Provider 初始化,則 Context 為空)。

?

小編的擴(kuò)展鏈接

《Android 基礎(chǔ)組件 全家桶》
?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容