本文參考 Android Context 是什么?進(jìn)行的自我學(xué)習(xí)總結(jié)。
我們會(huì)經(jīng)常用Context來獲取資源,啟動(dòng)服務(wù)痢缎,創(chuàng)建View,啟動(dòng)Activity,綁定Service世澜,發(fā)廣播,etc独旷。
** 帶著問題:**
Context的定義?
Context源碼實(shí)現(xiàn)寥裂?
Context分類及使用注意點(diǎn)嵌洼?
定義:提供一個(gè)應(yīng)用運(yùn)行所需要的信息,資源抚恒,系統(tǒng)服務(wù)的一個(gè)運(yùn)行環(huán)境咱台,資源依賴。通俗說是“上下文”俭驮。
AndroidStudio里用Type Hierarchy(ctrl+h)看下類的繼承派生關(guān)系:
可以清晰看到Context有二個(gè)直接子類回溺,MockContext是用于測試的,ContextWrapper是我們要關(guān)心的混萝。
Application與Service都繼承自ContextWrapper遗遵。
Activity不是直接繼承ContextWrapper,而是繼承ContextThemWrapper逸嘀。ContextThemWrapper擴(kuò)展了主題相關(guān)的方法车要。
有人說Application也有主題,Application的主題最終由Activity承載崭倘。
LayoutInflater from方法也是調(diào)用系統(tǒng)服務(wù)來實(shí)現(xiàn)翼岁。
Application類是繼承自ContextWrapper類。
在attach方法中司光,調(diào)用父類ContextWrapper中的attachBaseContext方法來對ContextWrapper的成員變量mBase賦值成ContextImpl對象琅坡。
Application的attachBaseContext()方法是挺重要的,覆蓋它一些需要搶時(shí)間的全局初始化的工作。
解開了java程序由main方法啟動(dòng)的疑惑:每一個(gè)App應(yīng)用都是由ASM通過Binder機(jī)制創(chuàng)建一個(gè)新的進(jìn)程然后調(diào)用ActivityThread類中的main方法開始的残家。整個(gè)App應(yīng)用的入口在ActivityThread.main方法里面榆俺!
getApplication和getApplicationContext得到的對象本質(zhì)沒有區(qū)別,僅僅是返回類型和實(shí)現(xiàn)方法的地方不同,getApplication是Activity才有的茴晋。
Dialog與startActivity啟動(dòng)非FLAG_ACTIVITY_NEW_TASK標(biāo)記的Activity Context必須是Activity類型陪捷。
LayoutInflater.from(Context context)由于只是靜態(tài)資源加載,Context無限制诺擅。
view的創(chuàng)建與getResource市袖,資源加載理論是可以使用任意的Context,但盡量用Activity類型.getResource().getDrawable(R.drawable....)在小米4.4.2系統(tǒng)用application類型的會(huì)造成了崩潰掀虎,改用Activity就沒事了
特別注意在A瓒ⅰ8斗恪烹玉!異步延時(shí)!2病二打!使用Activity創(chuàng)建Dialog顯示,極易造成Crash。Activity是否finish掂榔。
if (mActivity.isFinishing()) {
Log.e(TAG, "onPostExecute: mActivity.isFinishing()"); return;
}
builder.show();
Unable to add window -- token android.os.BinderProxy@25f520a6 is not valid; is your activity running?
同步延時(shí)就類ANR了继效。