Context——Context详解(6)

来源:互联网 发布:电脑淘宝怎么延长收货 编辑:程序博客网 时间:2024/06/02 02:26

http://www.cnblogs.com/android100/p/Android-Context.html



Context是一个抽象基类,我们通过它访问当前包的资源(getResources、getAssets)和启动其他组件(Activity、Service、Broadcast)以及得到各种服务(getSystemService),当然,通过Context能得到的不仅仅只有上述这些内容。对Context的理解可以来说:Context提供了一个应用的运行环境,在Context的大环境里,应用才可以访问资源,才能完成和其他组件、服务的交互,Context定义了一套基本的功能接口,我们可以理解为一套规范,而Activity和Service是实现这套规范的子类,这么说也许并不准确,因为这套规范实际是被ContextImpl类统一实现的,Activity和Service只是继承并有选择性地重写了某些规范的实现。

Application、Activity和Service作为Context的区别

首先,它们都间接继承了Context,这是它们的相同点。

不同点,可以从几个方面来说:首先看它们的继承关系

Activity的继承关系

通过对比可以清晰地发现,Service和Application的类继承关系比较像,而Activity还多了一层继承ContextThemeWrapper,这是因为Activity有主题的概念,而Service是没有界面的服务,Application更是一个抽象的东西,它也是通过Activity类呈现的。

Activity对象中ContextImpl的创建

代码为ActivityThread中的performLaunchActivity方法

if (activity != null) {      Context appContext = createBaseContextForActivity(r, activity);      /**      *  createBaseContextForActivity中创建ContextImpl的代码      *  ContextImpl appContext = new ContextImpl();      *  appContext.init(r.packageInfo, r.token, this);      *  appContext.setOuterContext(activity);      */      CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());      Configuration config = new Configuration(mCompatConfiguration);      if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "              + r.activityInfo.name + " with config " + config);      activity.attach(appContext, this, getInstrumentation(), r.token,              r.ident, app, r.intent, r.activityInfo, title, r.parent,              r.embeddedID, r.lastNonConfigurationInstances, config);        if (customIntent != null) {          activity.mIntent = customIntent;      }      ...  } 

可以看出,Activity在创建的时候会new一个ContextImpl对象并在attach方法中关联它,需要注意的是,创建Activity使用的数据结构是ActivityClientRecord。

Application对象中ContextImpl的创建

代码在ActivityThread中的handleBindApplication方法中,此方法内部调用了makeApplication方法

public Application makeApplication(boolean forceDefaultAppClass,          Instrumentation instrumentation) {      if (mApplication != null) {          return mApplication;      }        Application app = null;        String appClass = mApplicationInfo.className;      if (forceDefaultAppClass || (appClass == null)) {          appClass = "android.app.Application";      }        try {          java.lang.ClassLoader cl = getClassLoader();          ContextImpl appContext = new ContextImpl();          appContext.init(this, null, mActivityThread);          app = mActivityThread.mInstrumentation.newApplication(                  cl, appClass, appContext);          appContext.setOuterContext(app);      } catch (Exception e) {          if (!mActivityThread.mInstrumentation.onException(app, e)) {              throw new RuntimeException(                  "Unable to instantiate application " + appClass                  + ": " + e.toString(), e);          }      }      ...  } 

看代码发现和Activity中ContextImpl的创建是相同的。

 

Service对象中ContextImpl的创建

通过查看代码发现和Activity、Application是一致的。分析到这里,那么三者的Context有什么区别呢?没有区别吗?尽管如此,有一些细节是确定的:Dialog的使用需要Activity,在桌面上我们采用Application的Context无法弹出对话框,同时在桌面上想启动新的activity,我们需要为intent设置FLAG_ACTIVITY_NEW_TASK标志,否则无法启动activity,这一切都说明,起码Application的Context和Activity的Context还是有区别的,当然这也可能不是Context的区别,因为在桌面上,我们的应用没有界面,这意味着我们能干的事情可能受到了限制,事情的细节目前我还没有搞的很清楚。


0 0
原创粉丝点击