android 中的context 顾名思义就是 上下文的意思,每个安卓应用在进行运行的时候,都要在其完整的安卓工程环境下进行运行
其context的类继承:
由图可以看出,其实常见的Application Service 以及Activity 都是继承context的,在一个应用程序中,一个Service ,Activity 都是一个context 就好像 Toast的弹出一样,并不是 直接凭空进行弹出的必须要在activity的环境下进行弹出,所以在toast进行弹出时要传入一个activity的context。
由此可见,一个应用程序中的context个数为:使用的服务数+活动数+唯一的application全局应用context.
而在上面的ContextWrapper 和 Contextlmpl 类,其实ContextWrapper是一个接口,其规定继承的类必须拥有context 而具体的context 内的信息的获取,要交给ContextThemeWrapper来实现,
/**
* 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 ;
后面的方法全部是调用 mBase 的方法而已。
然而这个mBase 就是ContextImpl的实现类实现的。
当其Application方法执行时,会首先调用构造方法,如果在构造方法中就调用其context的函数,来获取上下文信息,就会报错,因为此时的mBase 还没有被attachBaseContext方法进行赋值,如果想最快的获取其上下文信息
可以不必onCreate()中调用,可以在attachBaseContext赋值完mBase后调用。
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
// 在这里调用Context的方法会崩溃
super.attachBaseContext(base);
// 在这里可以正常调用Context的方法
}