Android Context深入理解

在應用開發過程中我們經常用到Context,有Activity的Context,Application的Context,還有Service的Context,這三個有什么區別?Context在Android中到底是個什么東西?本文闡述Context的定義,Context具體功能實現,以及各種Context的區別和使用方法。最后,本文總結了Android N適配時使用Context的一些注意事項。

定義


Context通常被翻譯成上下文,它在Android中代表場景。一個Context就是一個場景,一個場景代表著一組用戶與應用交互的過程。比如聽音樂、打電話、發短信,這都分別對應著一個場景。

實現


Context是一個抽象類,定義了訪問應用環境全局信息的接口;包括訪問應用程序資源、打開Activity(startActivity())、啟動Service(startService())、發送廣播,文件讀寫等。Activity,Service以及Application均繼承自Context,所以我們經常使用的startActivity(),getResource(),getSharedPreference(),getExternalFilesDir(),deleteDatabase()等等方法都來自于Context。UML類圖如下所示:
Context

由上圖可知,Activity,Service,Application并沒有直接繼承Context,而是繼承自ContextWrapper。ContextWrapper是Context的包裝類,內部包含一個Context的引用,指向Context的具體實現類ContextImpl。ContextWrapper內部的所有方法直接調用ContextImpl對應的方法。

ContextImpl在ActivityThread創建Activity,Service以及Application時被實例化。所以每個應用都有多個ContextImpl實例。ContextImpl內部包含一個指向ActivityThread.PackageInfo的引用mPackageInfo。ContextImpl內部方法功能都是通過調用mPackageInfo對象來實現的。

ActivityThread.PackageInfo是一個重量級類,每一個應用程序僅有一個ActivityThread.PackageInfo實例,所有ContextImpl內部的mPackageInfo都指向ActivityThread.PackageInfo的唯一實例。

使用區別


Application、Activity以及Service均繼承自Context,在初始化ContextImpl時使用的參數不一樣,所以對應的使用場景也不一樣。

Application對應著應用程序全局相關的場景,比如我們可以寫一個全局工具類,使用Application獲取類加載器,Looper,或者做一些處理權限相關的操作等等(當然Activity與Service也可以)。雖然加載UI相關資源在使用上是合法的,但加載的布局會忽略用戶設置訂樣式并會使用系統默認樣式,而且在Android N的分屏模式中會出現不可預知的問題。所以不推薦使用Application的Context加載UI資源。

對話框只能存在于父窗口中,所以只能在Activity中打開,使用Application或者Service的Context會報異常:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application。

不推薦在Application以及Service中使用startActivity()方法,因為它們會在新的Task中打開Activity。

適配Android N新特性


谷歌在安卓7的預覽版中增加了多窗口分屏功能,能夠并排的同時使用兩個應用。多窗口利用Android的資源系統,基于窗口的大小動態的調整配置。在調整窗口大小時,屏幕大小最小寬度和朝向都會實時更新。所以我們需要使用正確的Context加載資源。對于UI相關資源(布局),最好使用其所在Activity的Context加載。如果使用Application加載布局UI等資源,有可能會出現在多窗口模式下無法正常工作的情況。


參考資料
Context的應用場景
Android N適配以及對應中文翻譯
Context詳解

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容