Context

基本类结构
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190623152035355.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzcyNDc0Mg==,size_16,color_FFFFFF,t_70

public class ContextWrapper extends Context {
	Context mBase;
	public ContextWrapper(Context base) {
        mBase = base;
    }
	
    //为ContextWrapper设置它的ContextImpl
	protected void attachBaseContext(Context base) {
	 	if (mBase != null) { 
	 		throw new IllegalStateException("Base context already set"); 
	 	}
	  	mBase = base; 
	}

	public Context getBaseContext() {
        return mBase;
    }
}

这里的base就是一个ContextImpl类,base负责Context的实际的处理逻辑

Activity中的contextImpl的创建过程:

启动Activity时会调用ActivityThread的以下方法:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        Activity activity = null;
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
        	//创建与Activity关联的ContextImpl 
            Context appContext = createBaseContextForActivity(r, activity); 	 //1
            //调用attach把activity关联到新创建的contextImpl
            //没有关联contextImpl的Context很多方法是不可用的,因为contextImpl是实现方法的实体
            activity.attach(appContext, this, getInstrumentation(), r.token, app, r.intent, ...);	//2
        }
        return activity;
    }

注释1处:

    private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
        ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
        appContext.setOuterContext(activity);
        Context baseContext = appContext;
        return baseContext;
    }

在注释2处activity.attach()方法中调用了attachBaseContext(),将新创建的ContextImpl赋值给mBase

Application创建ContextImpl的过程:

//冷启动时当前应用还没有Application,创建Application
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
	if (mApplication != null) {
            return mApplication;
    }
    java.lang.ClassLoader cl = getClassLoader();
    //和Activity一样都调用了ContextImpl.createActivityContext
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);		//1
    appContext.setOuterContext(app);
    mApplication = app;
    return app;
}

注释1处:

static public Application newApplication(Class<?> clazz, Context context){
	Application app = (Application)clazz.newInstance();
	app.attach(context);			//里面调用了attachBaseContext(context)去关联contextImpl
	return app;
}

每个ContextWrapper都有不同的ContextImpl,如何保证不同ContextImpl访问的资源是同样的?
看ContextImpl的源码:

class ContextImpl extends Context {
	private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
            new HashMap<String, ServiceFetcher>();
	private final ResourcesManager mResourcesManager;
    private final Resources mResources;

	private ContextImpl(ActivityThread mainThread,LoadedApk packageInfo,...){
		mResourcesManager = ResourcesManager.getInstance();				//单例
		Resources resources = packageInfo.getResources(mainThread);		//packageInfo是同一个
		mResources = mResourcesManager.getTopLevelResources(....);
	}
    
	public AssetManager getAssets() {
        return getResources().getAssets();
    }
    
	public Resources getResources() {
        return mResources;
    }
    
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
		return new ContextImpl(null, mainThread, ...)
	}

	private static void registerService(String serviceName, ServiceFetcher fetcher) {
		SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
	}
	
	public Object getSystemService(String name) {
		 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
		 return fetcher == null ? null : fetcher.getService(this);
	}
}

getApplication和getApplicationContext的区别:
getApplication方法只有Activity和Service才有,它返回了一个Application对象;
getApplicationContext()是Context的方法,它返回了一个Context对象
二者返回的对象是同一个Application

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值