Context字面意思上下文,位於framework package的android.content.Context中,其實該類爲LONG型,相似Win32中的Handle句柄,不少方法須要經過 Context才能識別調用者的實例,好比說Toast的第一個參數就是Context,通常在Activity中咱們直接用this代替,表明調用者的 實例爲Activity,而到了一個button的onClick(View view)等方法時,咱們用this時就會報錯,因此咱們可能使用ActivityName.this來解決,主要緣由是由於實現Context的類主要有Android特有的幾個模型,Activity、Service以及BroadcastReceiver。php
Context提供了關於應用環境全局信息的接口。它是一個抽象類,它的執行被Android系統所提供。它容許獲取以應用爲特徵的資源和類型。同時啓動應用級的操做,如啓動Activity,broadcasting和接收intents。html
兩種類型的Contextandroid
在android中context能夠做不少操做,可是最主要的功能是加載和訪問資源。在android中有兩種context,一種是 application context,一種是activity context,一般咱們在各類類和方法間傳遞的是activity context。好比一個activity的onCreateweb
|
把activity context傳遞給view,意味着view擁有一個指向activity的引用,進而引用activity佔有的資源:view hierachy, resource等。ui
內存泄露this
這樣若是context發生內存泄露的話,就會泄露不少內存。這裏泄露的意思是gc沒有辦法回收activity的內存。url
註釋:爲何GC沒有辦法回收相應的內存,我的感受是由於傳遞Context會增長對象指針的引用計數,因此基於智能指針技術的GC沒法釋放相應的內存。spa
當屏幕旋轉的時候,系統會銷燬當前的activity,保存狀態信息,再建立一個新的。好比咱們寫了一個應用程序,它須要加載一個很大的圖片,咱們不但願每次旋轉屏幕的時候都銷燬這個圖片,從新加載。實現這個要求的簡單想法就是定義一個靜態的Drawable,這樣Activity 類建立銷燬它始終保存在內存中。實現相似:
|
這段程序看起來很簡單,可是卻問題很大。當屏幕旋轉的時候會有leak(即gc無法銷燬activity)。咱們剛纔說過,屏幕旋轉的時候系統會銷燬當前的activity。可是當drawable和view關聯後,drawable保存了view的 reference,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能銷燬,它所引用和間接引用的都不能銷燬,這樣系統就沒有辦法銷燬當前的activity,因而形成了內存泄露。gc對這種類型的內存泄露是無能爲力的。避免這種內存泄露的方法是避免activity中的任何對象的生命週期長過activity,避免因爲對象對 activity的引用致使activity不能正常被銷燬。
爲了防止內存泄露,咱們應該注意如下幾點:
不要讓生命週期長的對象引用activity context,即保證引用activity的對象要與activity自己生命週期是同樣的
對於生命週期長的對象,可使用application context
避免非靜態的內部類,儘可能使用靜態類,避免生命週期問題,注意內部類對外部對象引用致使的生命週期變化
application context
咱們可使用application context。application context伴隨application的一輩子,與activity的生命週期無關。application context能夠經過Context.getApplicationContext或者Activity.getApplication方法獲取。
而製造Application context的方法在這裏能夠找到
http://stackoverflow.com/questions/708012/android-how-to-declare-global-variables/708317#708317
Java裏面一般是用一個static的變量(例如singleton之類的)來同步activity之間(程序裏面類之間)的狀態。在android裏面比較靠譜的作法是用application context來關聯這些狀態。
每一個activity都是context,裏面包含了運行時的狀態。一樣application也有一個context,android會保證這個context是惟一的實例。
作一個你本身的application context須要繼承android.app.Application,而後在app的manifest裏面說明這個類。android會自動幫你建立你這個類的實例,接着你用Context.getApplicationContext()方法就能在各個activity裏
面得到這個application context了。
|
下面介紹Context的一些get方法,經過這些get方法能夠獲取應用環境全局信息:
Return the context of the single, global Application object of the current process.
Return the full application info for this context's package.
Return a ContentResolver instance for your application's package.
Return PackageManager instance to find global package information.
Return the name of this application's package.
Return a Resources instance for your application's package.
Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.
Return a localized string from the application's package's default string table.
Return the handle to a system-level service by name. The class of the returned object varies by the requested name. Currently available names are:
參考博客:http://blog.chinaunix.net/space.php?uid=17102734&do=blog&id=2830227