Android中的Context、ContextImpl和ContextWrapper详解

247 阅读3分钟

Android中的Context、ContextImpl和ContextWrapper详解

context关系

在Android开发里,ContextContextImplContextWrapper 是与上下文环境相关的重要类,下面分别介绍:

1. Context

概念

Context 是一个抽象类,它就像一个访问应用全局信息的接口。通过 Context,可以访问应用的资源、类加载器,还能进行启动 Activity、服务,发送广播等操作。在 Android 系统中,许多操作都需要 Context 才能完成。

作用

它是 Android 应用的基础,为应用提供运行时的环境信息。例如,要显示一个 Toast 提示框,就需要 Context 对象。

示例

Toast.makeText(context, "This is a toast", Toast.LENGTH_SHORT).show();

2. ContextImpl

概念

ContextImplContext 的具体实现类。它包含了大量的具体实现代码,是 Context 功能的真正执行者。ContextImpl 持有很多系统服务的引用,负责与系统底层进行交互。

作用

当调用 Context 的各种方法时,实际上最终是由 ContextImpl 来完成具体操作的。比如,启动 Activity、获取资源等操作,都是在 ContextImpl 中实现的。

创建

ContextImpl 对象通常由系统在应用启动或者组件创建时自动创建,开发者一般不需要直接创建 ContextImpl 对象。

3. ContextWrapper

概念

ContextWrapper 是一个包装类,它继承自 ContextContextWrapper 类的主要作用是对 Context 对象进行包装,它内部持有一个 Context 对象的引用(通常是 ContextImpl 对象),并将大部分方法的调用委托给这个内部的 Context 对象。

作用

ContextWrapper 类可以让开发者在不改变原有 Context 对象的基础上,对 Context 的功能进行扩展或者修改。例如,ActivityService 等类都继承自 ContextWrapper,它们通过 ContextWrapper 来使用 Context 的功能,并且可以在自身的类中添加额外的逻辑。

示例

public class MyContextWrapper extends ContextWrapper {
    public MyContextWrapper(Context base) {
        super(base);
    }

    // 可以在这里添加自定义的方法或者重写父类的方法
}

三者关系

  • Context 是一个抽象类,定义了上下文环境的基本接口。
  • ContextImplContext 的具体实现类,负责实现 Context 定义的各种功能。
  • ContextWrapper 是对 Context 的包装类,它通过持有一个 Context 对象(通常是 ContextImpl),并将方法调用委托给这个对象,同时允许开发者对 Context 的功能进行扩展。

在实际开发中,开发者一般使用 Context 类型的引用,而不需要关心具体是 ContextImpl 还是 ContextWrapper。系统会根据不同的场景创建合适的对象来完成相应的操作。 ##总结 在 Android 中,一个进程可以有多个 Context,但它们的作用和生命周期有所不同。通常,进程中会有一个全局的 Application Context,其他 Activity Context、Service Context、BroadcastReceiver Context 等则根据具体组件的生命周期而创建和销毁。

虽然我们可以在应用中使用不同类型的 Context,但需要特别注意不要误用 Activity Context 或 Service Context,以避免内存泄漏问题。一般来说,推荐使用 Application Context,它的生命周期较长,不容易引起内存泄漏。

##问题:一个进程会创建多少个Context 结论: 一个进程中会创建一个Application的Context+创建的Activity+创建的Service 所以数量是:Application+当前存在的Activity+Service

	1:创建Application
	ActivityThread.class
	  private void handleBindApplication(AppBindData data) {
	  ...
	    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
	  ...
	  }

	2:创建Activity对象
	ActivityThread.class
	  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
			...
			
			    ContextImpl appContext = createBaseContextForActivity(r);
                              ...
                              //将contextimpl 赋值给 ContextWrapper 的mBase
                            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.activityConfigCallback,
                                        r.assistToken, r.shareableActivityToken);

                            ....
			...
	  
	  }
	  
	    private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
		
				...
				 ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
				...
		}
		
	ContextImpl.class

	  static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
            Configuration overrideConfiguration) {
				...
			    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY,
                attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader,
                null);
			...
		}
			

	3:创建Service 对象
	
	ActivityThread.class
	
    @UnsupportedAppUsage
    private void handleCreateService(CreateServiceData data) {
        ...
		
		   Application app = packageInfo.makeApplicationInner(false, mInstrumentation);
		   
		...
	}
	LoadedApk.class
   private Application makeApplicationInner(boolean forceDefaultAppClass,
            Instrumentation instrumentation, boolean allowDuplicateInstances) {
			...
			  ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
			...
			}

	  
	4:广播(广播正常情况不创建Context)
		  private void handleReceiver(ReceiverData data) {
			Application   app = packageInfo.makeApplicationInner(false, mInstrumentation);
            context = (ContextImpl) app.getBaseContext();
			//默认用Application 的Context  不创建Context 实例
            if (data.info.splitName != null) {
			//特殊情况创建
                context = (ContextImpl) context.createContextForSplit(data.info.splitName);
            }
            if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
                final String attributionTag = data.info.attributionTags[0];
				//特殊情况创建
                context = (ContextImpl) context.createAttributionContext(attributionTag);
            }
		  }