Android Context 上下文對象詳解

context使用很多次了,還屬于經(jīng)常踩坑的一個點(diǎn),今天沒事(武漢加油(? ??_??)?)就總結(jié)一下,本文參考:http://blog.csdn.net/lmj623565791/article/details/40481055

context太常用了,加載資源、啟動一個新的Activity、獲取系統(tǒng)服務(wù)、獲取內(nèi)部文件(夾)路徑、創(chuàng)建View操作時等都需要Context的參與。那么context到底是什么呢?官方解釋是上下文對象,也就是用戶與操作系統(tǒng)交互的對象,過程;包括交互的界面,以及隱藏在背后的數(shù)據(jù)信息。

從技術(shù)層面剖析context,那么它是一個抽象類,可以直接從代碼看出它的結(jié)構(gòu)是怎樣的

圖1

可以看到Activity、Service、Application都是Context的子類;

也就是說,Android系統(tǒng)的角度來理解:Context是一個場景,代表與操作系統(tǒng)的交互的一種過程。從程序的角度上來理解:Context是個抽象類,而Activity、Service、Application等都是該類的一個實(shí)現(xiàn)。

在仔細(xì)看一下上圖:Activity、Service、Application都是繼承自ContextWrapper,而ContextWrapper內(nèi)部會包含一個base context,由這個base context去實(shí)現(xiàn)了絕大多數(shù)的方法。

理解了context之后我們看它的使用的方式:一般在avtivity中,有兩種使用方式:xxxactivity. this和getApplicationContext這兩種傳入方式,那這兩種方式有何不同呢?一般在匿名內(nèi)部類的時候不能使用. this的方式,只能使用getApplicationContext的方式,所以這兩種方式返回的對象肯定不同,一個是Activity的實(shí)例,一個是Application的實(shí)例。因此這兩種方式不能亂使用。

當(dāng)我們在編寫工具類的時候常常需要context的參與去訪問資源,訪問系統(tǒng)管理類等,這樣的情況下就要注意context的使用了。

這種工具類內(nèi)部保持了一個Context的引用;這個Context哪來的我們不能確定,很大的可能性,你在某個Activity里面為了方便,直接傳了個this;這樣問題就來了,我們的這個類中的sInstance或者方法是一個static且強(qiáng)引用的,在其內(nèi)部引用了一個Activity作為Context,也就是說,我們的這個Activity只要我們的項(xiàng)目活著,就沒有辦法進(jìn)行內(nèi)存回收。而我們的Activity的生命周期肯定沒這么長,所以造成了內(nèi)存泄漏。這時候你說改成軟引用,這樣暫時沒問題了,但是activity被回收了怎么辦呢,就會造成拋出NullPointException的異常。又說那全部改成getApplicationContext就沒有問題了,好我們暫時解決了內(nèi)存泄露的問題。

但是又有一個問題,上面說了activity的context和application的context的使用場景雖然有些重合場景,但還是有不同的地方。并非所有Activity中的context都可以用application Context來表示。


下面列出context的應(yīng)用場景

圖2

大家注意看到有一些NO上添加了一些數(shù)字,其實(shí)這些從能力上來說是YES,但是為什么說是NO呢?下面一個一個解釋:

數(shù)字1:啟動Activity在這些類中是可以的,但是需要創(chuàng)建一個新的task。一般情況不推薦。

數(shù)字2:在這些類中去layout inflate是合法的,但是會使用系統(tǒng)默認(rèn)的主題樣式,如果你自定義了某些樣式可能不會被使用。

數(shù)字3:在receiver為null時允許,在4.2或以上的版本中,用于獲取黏性廣播的當(dāng)前值。(可以無視)

注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因?yàn)樵谄鋬?nèi)部方法中都有一個context用于使用。

好了,這里我們看下表格,重點(diǎn)看Activity和Application,可以看到,和UI相關(guān)的方法基本都不建議或者不可使用Application,并且,前三個操作基本不可能在Application中出現(xiàn)。實(shí)際上,只要把握住一點(diǎn),凡是跟UI相關(guān)的,都應(yīng)該使用Activity做為Context來處理;其他的一些操作,Service,Activity,Application等實(shí)例都可以,當(dāng)然了,注意Context引用的持有,防止內(nèi)存泄漏。

至此,Context的分析基本完成了,希望大家在以后的使用過程中,能夠稍微考慮下,這里使用Activity合適嗎?會不會造成內(nèi)存泄漏?會不會拋出異常?

今天的分析到此結(jié)束

~~~~~~~~~

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

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

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