谈一下ContextImpl

CSDN话题挑战赛第2期
参赛话题:面试宝典

1. 应用中一共多少个实例?

首先我们将Context的继承结构梳理一下
在这里插入图片描述
通过查看Context的继承结构,我们可以看到
Context的直接子类是ContextWrapper,我们看下ContextWrapper的初始化相关方法,我们用到的几个子类实现分别有ApplicationServiceActivity

//ContextWrapper
Context mBase;
public ContextWrapper(Context base) {
    mBase = base;
}

 protected void attachBaseContext(Context base) {
    if (mBase != null) {
        throw new IllegalStateException("Base context already set");
    }
    mBase = base;
}

构造方法传递的都是null,另外一个方法attachBaseContext也是用来初始化mBase的,我们分别查看一下各个具体子类的相关实现

Application

frameworks/base/core/java/android/app
-> ActivityThread.performLaunchActivity()
-> LoadedApk.makeApplication()
-> Instrumentation.newApplication()
-> Application.attach()
	-> ContextWrappter.attachBaseContext()
	
// 创建ContextImpl实例步骤可参考activity下ContextImpl实例创建步骤
// 结论是通过 new ContextImpl方式创建实例
    
 public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
      // 反射构建application对象
      Application app = getFactory(context.getPackageName())
              .instantiateApplication(cl, className);
      app.attach(context);
      return app;
  }

Service

framework/base/services/core/java/com/android/server/am
ActivityManagerService
-> startService()
ActiveServices
-> startServiceLocked()
-> startServiceInnerLocked()
    -> realStartServiceLocked()
	-> ActivityThread.scheduleCreateService()
		-> handleCreateService()
		-> Service.attach()
		-> ContextWrappter.attachBaseContext()
// ActivityThread    
private  void handleCreateService(CreateServiceData data){
    //...
    Service service = null;
    //...
    // 反射方式创建service对象
    service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
    // 创建ContextImpl对象( ContextImpl context = new ContextImpl())
    ContextImpl context = ContextImpl.getImpl(service.createServiceBaseCotnext(this,packageInfo));
    //...
    // service绑定ContextImpl
    service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());
    service.onCreate();
}

Activity

frameworks/base/core/java/android/app
-> ActivityThread.performLaunchActivity()
-> Activity.attach()
	-> attachBaseContext()
	-> ContextThremeWrapper.attachBaseContext()
	-> ContextWrappter.attachBaseContext()

/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //...
    // 创建ContextImpl实例
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try{
        // 创建activity实例
       activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); 
    }
    //...
    try{
        // activity绑定contextImpl
        activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken, r.shareableActivityToken);
        //...
        // 回调activity的onCreate()方法
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
    }
}
 private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
     // ContextImpl impl = new ContextImpl(),通过new的方式创建实例
     ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
     //...
     return appContext;
     
 }

查看上述几个具体实现类的ContextImpl的实例绑定,我们可以得出一个应用总共的ContextImpl实例个数为:1(Application) + Activity个数 + Service个数

2. 如何获取ContextImpl实例?

查看ContextImpl类,我们知道该类不是public,应用程序是无法获取到该类并且通过new的形式创建实例。我们可以通过getImpl的方法,进行反射获取

static ContextImpl getImpl(Context context) {
    Context nextContext;
    while ((context instanceof ContextWrapper) &&
            (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
        context = nextContext;
    }
    return (ContextImpl)context;
}

try{
	Class<?> clazz=Class.forName("android.app.ContextImpl");
	Method method=clazz.getDeclaredMethod("getImpl",Context.class);
	method.setAccessible(true);
	// 获取ContextImpl的实例
	Object mContextImpl=method.invoke(null,this);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值