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的方法
}