淺析Android Context

來源:互聯網
上載者:User

標籤:android   context   getapplicationcontex   記憶體泄露   繼承關係   

一:什麼是Context?

    Context,sdk中的解釋如下:interface to global information about an application environment.This is an abstract class whose implementation is provided by the Android System.It allows access to application-specific resources and classes,as well as up-calls for application-level operations such as launching activities,broadcasting and receiving intents,etc.

    簡單的總結為三條:

    1.它描述的是一個應用程式的環境的資訊,可以被稱作為上下文。

    2.該類是一個抽象類別,Android提供了該抽象類別的具體實作類別。

    3.通過它我們可以擷取應用程式的資源和類,也包括採取一些應用層級的操作,例如,啟動一個Activity,發送廣播,接收Intent.

二:Context抽象類別的繼承關係

    由我們可以看出,Activity,service,Application實則全為Context的子類。


三:Context執行個體的建立時機以及數目

    通常來說,程式建立Context執行個體的時機為以下三種情況:

    1.建立Application對象時,而且整個App共有一個Application對象。

    2.建立Service對象時

    3.建立Activity對象時

    由上可知,一個應用程式中Context執行個體個數的計算公式為:

            總Context數 = Service個數 + Activity個數 + 1(Application對應的Context執行個體)

四:Context的擷取方式以及全域擷取Context的技巧

    因為Activity,Service本身就是一個context對象,所以在其中擷取Context非常簡單,但當脫離了這些與Context類有緊密關係的類時,我們該如何獲得呢?當然這也有許多方法可以獲得,但我在此給大家分享一種方法,定製一個自己的Application類,以便於管理程式內一些全域的狀態資訊,如Context。建立一個MyApplication繼承自Application,代碼如下:(以下代碼來自《第一行代碼》)

<span style="font-size:14px;">public class MyApplication{private static Context context;@overridepublic void onCreate(){context = getApplicationContext();}public static Context getContext(){return context;}}</span>
    接下來我們需要告知系統,當程式啟動的時候應該初始化MyApplication而不是預設的Application類,操作也很簡單,修改AndroidManifest.xml檔案的<application>標籤下的內容:

<application    android:name="com.example.hhw.MyApplication"    ....></appliaction>

    之後,你可以通過以下方式在你想用Context的任何地方得到它。
<span style="font-size:14px;">MyApplication.getContext();</span>

五:Activity,Application的Context以及記憶體泄露

    首先,Activity的Context和Application的Context肯定不是一個東西,一個是當前活動的Context,它的生命週期僅限於此活動,一個是整個應用程式的Context,它的生命週期伴隨著整個程式,鑒於Activity的Context的特點,濫用它往往會造成記憶體泄露,如下代碼所示:

<span style="font-size:14px;">public class TestContext{private static TestContext testContext;private Context context;private TestContext(Context context){this.context = context;}    public static synchronized TestContext getInstance(Context context){    if(null == testContext)    testContext = new TestContext(context);    return testContext;    }}</span>

    顯而易見,上述單例模式中textContext是強引用static類型,往往它的生命週期伴隨著整個應用程式,但你傳遞進來的Context若是一個Activity的,只要我們這個應用程式還活著,它就沒有辦法正常的回收,這就造成了記憶體的泄露。解決的方法很簡單,將初始化TestContext是傳遞的參數變為context.getApplicationContext()既可,因為用此方法獲得的是應用程式的context,因此就不用擔心記憶體泄露了。

public class TestContext{private static TestContext testContext;private Context context;private TestContext(Context context){this.context = context;}    public static synchronized TestContext getInstance(Context context){    if(null == testContext)    testContext = new TestContext(context.getApplicationContext());    return testContext;    }}


    既然如此的話,在能使用context的地方全部替換成context.getApplicationContext()不就皆大歡喜了嗎?很遺憾的來說,這樣不行,因為他們根本不是一個東西,它們的應用情境是不同的,並非所有的Activity的Context的情境,Application的Context依然可以,一下是我總結出來的一個表格,表示了它倆之間的應用情境:

  Application Activity
show a dialog NO YES
Layout Inflation NO YES
start an activity NO YES
Bild to a Service YES YES
Send a Broadcast YES YES
Register BrocastReceiver YES YES
start a service YES YES
load resource values YES YES
    其實我們只要把握住兩條原則即可:

    1.凡是和UI相關的,都不建議使用Application的Context.

    2..不要讓生命週期長的對象引用activity context,即保證引用activity的對象要與activity本身生命週期是一樣的,若不一樣,請考慮一下是否可以使用Application的Context.


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

淺析Android Context

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.