context 簡單理解

android 中的context 顧名思義就是 上下文的意思,每個(gè)安卓應(yīng)用在進(jìn)行運(yùn)行的時(shí)候,都要在其完整的安卓工程環(huán)境下進(jìn)行運(yùn)行

其context的類繼承:

由圖可以看出,其實(shí)常見的Application Service 以及Activity 都是繼承context的,在一個(gè)應(yīng)用程序中,一個(gè)Service ,Activity 都是一個(gè)context 就好像 Toast的彈出一樣,并不是 直接憑空進(jìn)行彈出的必須要在activity的環(huán)境下進(jìn)行彈出,所以在toast進(jìn)行彈出時(shí)要傳入一個(gè)activity的context。

由此可見,一個(gè)應(yīng)用程序中的context個(gè)數(shù)為:使用的服務(wù)數(shù)+活動數(shù)+唯一的application全局應(yīng)用context.

而在上面的ContextWrapper 和 Contextlmpl 類,其實(shí)ContextWrapper是一個(gè)接口,其規(guī)定繼承的類必須擁有context 而具體的context 內(nèi)的信息的獲取,要交給ContextThemeWrapper來實(shí)現(xiàn),

/**

* Proxying implementation of Context that simply delegates all of its calls to

* another Context.  Can be subclassed to modify behavior without changing

* the original Context.

*/

public class ContextWrapperextendsContext{

    Context mBase;

/**

    * Set the base context for this ContextWrapper.  All calls will then be

    * delegated to the base context.  Throws

    * IllegalStateException if a base context has already been set.

    *

*@parambase The new base context for this wrapper.

    */

protected void attachBaseContext(Context base){

if(mBase !=null) {

throw new IllegalStateException("Base context already set");

        }

        mBase = base;

    }

/**

*@returnthe base context as set by the constructor or setBaseContext

    */

public Context getBaseContext(){

return mBase;

    }

@Override

public AssetManager getAssets(){

return mBase.getAssets();

    }

@Override

public Resourcesget Resources(){

return mBase.getResources();

    }

@Override

public ContentResolver getContentResolver(){

return mBase.getContentResolver();

    }

@Override

public Looperget MainLooper(){

return mBase.getMainLooper();

    }

@Override

public Context getApplicationContext(){

return mBase.getApplicationContext();

    }

@Override

public String getPackageName(){

return mBase.getPackageName();

    }

@Override

public void startActivity(Intent intent){

        mBase.startActivity(intent);

    }

@Override

public void sendBroadcast(Intent intent){

        mBase.sendBroadcast(intent);

    }

@Override

public Intent registerReceiver(

        BroadcastReceiver receiver, IntentFilter filter){

return mBase.registerReceiver(receiver, filter);

    }

@Override

public void unregisterReceiver(BroadcastReceiver receiver){

        mBase.unregisterReceiver(receiver);

    }

@Override

public Component NamestartService(Intent service){

return mBase.startService(service);

    }

@Override

public boolean stopService(Intent name){

return mBase.stopService(name);

    }

@Override

public boolean bindService(Intent service, ServiceConnection conn,

intflags) {

return mBase.bindService(service, conn, flags);

    }

@Override

public void unbindService(ServiceConnection conn){

        mBase.unbindService(conn);

    }

@Override

public Object getSystemService(String name){

return mBase.getSystemService(name);

    }

    ......

}

在其attachBaseContext()方法中,將 傳入的Context base 賦值給mBase ;
后面的方法全部是調(diào)用 mBase 的方法而已。
然而這個(gè)mBase 就是ContextImpl的實(shí)現(xiàn)類實(shí)現(xiàn)的。

![]
image.png

當(dāng)其Application方法執(zhí)行時(shí),會首先調(diào)用構(gòu)造方法,如果在構(gòu)造方法中就調(diào)用其context的函數(shù),來獲取上下文信息,就會報(bào)錯(cuò),因?yàn)榇藭r(shí)的mBase 還沒有被attachBaseContext方法進(jìn)行賦值,如果想最快的獲取其上下文信息
可以不必onCreate()中調(diào)用,可以在attachBaseContext賦值完mBase后調(diào)用。

public class MyApplication extends Application {
    
    @Override
    protected void attachBaseContext(Context base) {
        // 在這里調(diào)用Context的方法會崩潰
        super.attachBaseContext(base);
        // 在這里可以正常調(diào)用Context的方法
    }
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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