天天看點

Android之Context 和 application context

對于上述的單例,大家應該都不陌生(請别計較getInstance的效率問題),内部保持了一個Context的引用;

這麼寫是沒有問題的,問題在于,這個Context哪來的我們不能确定,很大的可能性,你在某個Activity裡面為了友善,直接傳了個this;這樣問題就來了,我們的這個類中的sInstance是一個static且強引用的,在其内部引用了一個Activity作為Context,也就是說,我們的這個Activity隻要我們的項目活着,就沒有辦法進行記憶體回收。而我們的Activity的生命周期肯定沒這麼長,是以造成了記憶體洩漏。

那麼,我們如何才能避免這樣的問題呢?

有人會說,我們可以軟引用,嗯,軟引用,假如被回收了,你不怕NullPointException麼。

把上述代碼做下修改:

這樣,我們就解決了記憶體洩漏的問題,因為我們引用的是一個ApplicationContext,它的生命周期和我們的單例對象一緻。

這樣的話,可能有人會說,早說嘛,那我們以後都這麼用不就行了,很遺憾的說,不行。上面我們已經說過,Context和Application Context的差別是很大的,也就是說,他們的應用場景(你也可以認為是能力)是不同的,并非所有Activity為Context的場景,Application Context都能搞定。

下面就開始介紹各種Context的應用場景。

4、Context的應用場景

Android之Context 和 application context

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

數字1:啟動Activity在這些類中是可以的,但是需要建立一個新的task。一般情況不推薦。

數字2:在這些類中去layout inflate是合法的,但是會使用系統預設的主題樣式,如果你自定義了某些樣式可能不會被使用。

數字3:在receiver為null時允許,在4.2或以上的版本中,用于擷取黏性廣播的目前值。(可以無視)

注:ContentProvider、BroadcastReceiver之是以在上述表格中,是因為在其内部方法中都有一個context用于使用。

好了,這裡我們看下表格,重點看Activity和Application,可以看到,和UI相關的方法基本都不建議或者不可使用Application,并且,前三個操作基本不可能在Application中出現。實際上,隻要把握住一點,凡是跟UI相關的,都應該使用Activity做為Context來處理;其他的一些操作,Service,Activity,Application等執行個體都可以,當然了,注意Context引用的持有,防止記憶體洩漏。