context使用很多次了弯淘,還屬于經(jīng)常踩坑的一個(gè)點(diǎn),今天沒事(武漢加油(? ??_??)?)就總結(jié)一下,本文參考:http://blog.csdn.net/lmj623565791/article/details/40481055
context太常用了,加載資源乡恕、啟動(dòng)一個(gè)新的Activity、獲取系統(tǒng)服務(wù)俯萎、獲取內(nèi)部文件(夾)路徑傲宜、創(chuàng)建View操作時(shí)等都需要Context的參與。那么context到底是什么呢讯屈?官方解釋是上下文對(duì)象蛋哭,也就是用戶與操作系統(tǒng)交互的對(duì)象,過程涮母;包括交互的界面谆趾,以及隱藏在背后的數(shù)據(jù)信息。
從技術(shù)層面剖析context叛本,那么它是一個(gè)抽象類沪蓬,可以直接從代碼看出它的結(jié)構(gòu)是怎樣的
可以看到Activity、Service来候、Application都是Context的子類跷叉;
也就是說,Android系統(tǒng)的角度來理解:Context是一個(gè)場(chǎng)景,代表與操作系統(tǒng)的交互的一種過程云挟。從程序的角度上來理解:Context是個(gè)抽象類梆砸,而Activity、Service园欣、Application等都是該類的一個(gè)實(shí)現(xiàn)帖世。
在仔細(xì)看一下上圖:Activity、Service沸枯、Application都是繼承自ContextWrapper日矫,而ContextWrapper內(nèi)部會(huì)包含一個(gè)base context,由這個(gè)base context去實(shí)現(xiàn)了絕大多數(shù)的方法绑榴。
理解了context之后我們看它的使用的方式:一般在avtivity中哪轿,有兩種使用方式:xxxactivity. this和getApplicationContext這兩種傳入方式,那這兩種方式有何不同呢翔怎?一般在匿名內(nèi)部類的時(shí)候不能使用. this的方式窃诉,只能使用getApplicationContext的方式,所以這兩種方式返回的對(duì)象肯定不同姓惑,一個(gè)是Activity的實(shí)例褐奴,一個(gè)是Application的實(shí)例按脚。因此這兩種方式不能亂使用于毙。
當(dāng)我們?cè)诰帉懝ぞ哳惖臅r(shí)候常常需要context的參與去訪問資源,訪問系統(tǒng)管理類等辅搬,這樣的情況下就要注意context的使用了唯沮。
這種工具類內(nèi)部保持了一個(gè)Context的引用;這個(gè)Context哪來的我們不能確定堪遂,很大的可能性介蛉,你在某個(gè)Activity里面為了方便,直接傳了個(gè)this溶褪;這樣問題就來了币旧,我們的這個(gè)類中的sInstance或者方法是一個(gè)static且強(qiáng)引用的,在其內(nèi)部引用了一個(gè)Activity作為Context猿妈,也就是說吹菱,我們的這個(gè)Activity只要我們的項(xiàng)目活著,就沒有辦法進(jìn)行內(nèi)存回收彭则。而我們的Activity的生命周期肯定沒這么長(zhǎng)鳍刷,所以造成了內(nèi)存泄漏。這時(shí)候你說改成軟引用俯抖,這樣暫時(shí)沒問題了输瓜,但是activity被回收了怎么辦呢,就會(huì)造成拋出NullPointException的異常。又說那全部改成getApplicationContext就沒有問題了尤揣,好我們暫時(shí)解決了內(nèi)存泄露的問題搔啊。
但是又有一個(gè)問題,上面說了activity的context和application的context的使用場(chǎng)景雖然有些重合場(chǎng)景北戏,但還是有不同的地方坯癣。并非所有Activity中的context都可以用application Context來表示。
下面列出context的應(yīng)用場(chǎng)景
大家注意看到有一些NO上添加了一些數(shù)字最欠,其實(shí)這些從能力上來說是YES示罗,但是為什么說是NO呢?下面一個(gè)一個(gè)解釋:
數(shù)字1:?jiǎn)?dòng)Activity在這些類中是可以的芝硬,但是需要?jiǎng)?chuàng)建一個(gè)新的task蚜点。一般情況不推薦。
數(shù)字2:在這些類中去layout inflate是合法的拌阴,但是會(huì)使用系統(tǒng)默認(rèn)的主題樣式绍绘,如果你自定義了某些樣式可能不會(huì)被使用。
數(shù)字3:在receiver為null時(shí)允許迟赃,在4.2或以上的版本中陪拘,用于獲取黏性廣播的當(dāng)前值。(可以無視)
注:ContentProvider纤壁、BroadcastReceiver之所以在上述表格中左刽,是因?yàn)樵谄鋬?nèi)部方法中都有一個(gè)context用于使用。
好了酌媒,這里我們看下表格欠痴,重點(diǎn)看Activity和Application,可以看到秒咨,和UI相關(guān)的方法基本都不建議或者不可使用Application喇辽,并且,前三個(gè)操作基本不可能在Application中出現(xiàn)雨席。實(shí)際上菩咨,只要把握住一點(diǎn),凡是跟UI相關(guān)的陡厘,都應(yīng)該使用Activity做為Context來處理抽米;其他的一些操作,Service,Activity,Application等實(shí)例都可以雏亚,當(dāng)然了缨硝,注意Context引用的持有,防止內(nèi)存泄漏罢低。
至此查辩,Context的分析基本完成了胖笛,希望大家在以后的使用過程中,能夠稍微考慮下宜岛,這里使用Activity合適嗎长踊?會(huì)不會(huì)造成內(nèi)存泄漏?會(huì)不會(huì)拋出異常萍倡?
今天的分析到此結(jié)束
~~~~~~~~~