Android之Context底層原理

1.Context基本概念
Context的中文翻譯為:語境; 上下文; 背景; 環(huán)境厅瞎,在開發(fā)中我們經(jīng)常說稱之為“上下文”。從Android系統(tǒng)的角度來理解:Context是一個場景荔泳,代表與操作系統(tǒng)的交互的一種過程。Context在加載資源、啟動Activity、獲取系統(tǒng)服務(wù)晌区、創(chuàng)建View等操作都要參與 。從程序的角度上來理解:Context是個抽象類通贞,而Activity朗若、Service、Application等都是該類的一個實現(xiàn)滑频。
2.Context與Activity、Service唤冈、Application關(guān)系

Paste_Image.png

Context類本身是一個純abstract類峡迷,他有兩個具體的實現(xiàn)子類:ContextImpl和ContextWrapper。其中ContextWrapper類你虹,只是一個包裝而已绘搞,ContextWrapper構(gòu)造函數(shù)中必須包含一個真正的Context引用,同時ContextWrapper提供了attachBaseContext()用于給ContextWrapper對象中指定真正的Context對象傅物,調(diào)用ContextWrapper的方法都會被轉(zhuǎn)向其所包含的真正的Context對象夯辖。ContextThemeWrapper類,其內(nèi)部包含了與主題(Theme)相關(guān)的接口董饰,這里所說的主題就是指在AndroidMainifest.xml中通過android:theme為Application元素或者Activity元素指定的主題蒿褂。當然圆米,只有Activity才需要主題,Service是不需要主題的啄栓,Application同理娄帖。而ContextImpl類則真正實現(xiàn)了Context中的所有函數(shù),應(yīng)用程序中所調(diào)用的各種Context類的方法昙楚,其實現(xiàn)均來于該類近速。Context的兩個子類分工明確,其中ContextImpl是Context的具體實現(xiàn)類堪旧,ContextWrapper是Context的包裝類削葱。
3.Context作用域

Paste_Image.png

Activity的作用域最廣,Application和Service在啟動Activity需要創(chuàng)建一個新的task淳梦,一般不推薦析砸。layout infalte也是合法的,但是會使用系統(tǒng)默認的主題樣式谭跨,如果自定義某些樣式可能不會被使用
4.Context的使用
4.1Context的數(shù)量
一個應(yīng)用程序中到底有多少個Context呢干厚?根據(jù)Context的類型可以得出,一共有Application螃宙、Activity和Service三種類型蛮瞄,因此一個應(yīng)用程序的Context數(shù)量為:Context數(shù)量=Activity數(shù)量+Service數(shù)量+1
4.2如何獲取Context
1)View.getContext,返回當前Activity所在的應(yīng)用進程的Context對象,通常是當前正在展示的Activity對象2)Activity.getApplicationContext,獲取當前Activity所在的(應(yīng)用)進程的Context對象谆扎,通常我們使用Context對象時挂捅,要優(yōu)先考慮這個全局的進程Context。3)Activity.this返回當前的Activity實例堂湖,如果是UI控件需要使用Activity作為Context對象闲先,但是默認的Toast因為是系統(tǒng)層級的Windows,直接使用ApplicationContext則可无蜂。4)getApplication和getApplicationContext獲取的對象時一致的伺糠。但是getApplication方法只有在Activity和Service中才能調(diào)到。但例如BroadcasrReceiver中需要獲取Application斥季,則需要借助getApplicationContext()方法训桶。
4.3Context引起的內(nèi)測泄漏
1)錯誤的單例模式

public class Singleton {  
    private static Singleton instance;  
    private Context mContext;  
  
    private Singleton(Context context) {  
        this.mContext = context;  
    }  
  
    public static Singleton getInstance(Context context) {  
        if (instance == null) {  
            instance = new Singleton(context);  
        }  
        return instance;  
    }  
}```
即使Activity被銷毀掉,但因為它的引用還存在于一個Singleton中酣倾,就不可能被GC掉
2)View持有Activity引用

public class MainActivity extends Activity {
private static Drawable mDrawable;

@Override  
protected void onCreate(Bundle saveInstanceState) {  
    super.onCreate(saveInstanceState);  
    setContentView(R.layout.activity_main);  
    ImageView iv = new ImageView(this);  
    mDrawable = getResources().getDrawable(R.drawable.ic_launcher);  
    iv.setImageDrawable(mDrawable);  
}  

}```
有一個靜態(tài)的Drawable對象當ImageView設(shè)置這個Drawable時舵揭,ImageView保存了mDrawable的引用,而ImageView傳入的this是MainActivity的mContext躁锡,因為被static修飾的mDrawable是常駐內(nèi)存的午绳,MainActivity是它的間接引用,MainActivity被銷毀時映之,也不能被GC掉拦焚,所以造成內(nèi)存泄漏蜡坊。
5.總結(jié)
盡量使用Application的Context
不要讓生命周期長于Activity的對象持有其的引用
盡量不要在Activity中使用非靜態(tài)內(nèi)部類,因為非靜態(tài)內(nèi)部類會隱式持有外部類示例的引用耕漱,如果使用靜態(tài)內(nèi)部類算色,將外部實例引用作為弱引用持有

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市螟够,隨后出現(xiàn)的幾起案子灾梦,更是在濱河造成了極大的恐慌,老刑警劉巖妓笙,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件若河,死亡現(xiàn)場離奇詭異,居然都是意外死亡寞宫,警方通過查閱死者的電腦和手機萧福,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辈赋,“玉大人鲫忍,你說我怎么就攤上這事≡壳” “怎么了悟民?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長篷就。 經(jīng)常有香客問我射亏,道長,這世上最難降的妖魔是什么竭业? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任智润,我火速辦了婚禮,結(jié)果婚禮上未辆,老公的妹妹穿的比我還像新娘窟绷。我一直安慰自己,他們只是感情好咐柜,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布兼蜈。 她就那樣靜靜地躺著,像睡著了一般炕桨。 火紅的嫁衣襯著肌膚如雪饭尝。 梳的紋絲不亂的頭發(fā)上肯腕,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天献宫,我揣著相機與錄音,去河邊找鬼实撒。 笑死姊途,一個胖子當著我的面吹牛涉瘾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捷兰,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼立叛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贡茅?” 一聲冷哼從身側(cè)響起秘蛇,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顶考,沒想到半個月后赁还,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡驹沿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年艘策,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渊季。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡朋蔫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出却汉,到底是詐尸還是另有隱情驯妄,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布病涨,位于F島的核電站富玷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏既穆。R本人自食惡果不足惜赎懦,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望幻工。 院中可真熱鬧励两,春花似錦、人聲如沸囊颅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踢代。三九已至盲憎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胳挎,已是汗流浹背饼疙。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慕爬,地道東北人窑眯。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓屏积,卻偏偏與公主長得像,于是被迫代替她去往敵國和親磅甩。 傳聞我的和親對象是個殘疾皇子炊林,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容