本系列分四篇文章详细介绍Context, 这是第三篇

  • Android深入理解Context–Application中Context的创建过程

  • Android深入理解Context–Activity中Context的创建过程

  • Android深入理解Context–Service中Context的创建过程

  • Android深入理解Context–Context使用的误区

  • 因为本文是分析Service的Context创建流程,我们直接从ActivityThread.handleCreateService开始分析,如果不太明白这之前的逻辑的话,可以参考Service启动流程源码分析。

    @UnsupportedAppUsage    private void handleCreateService(CreateServiceData data) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.        unscheduleGcIdler();        LoadedApk packageInfo = getPackageInfoNoCheck(                data.info.applicationInfo, data.compatInfo);        Service service = null;        try {            //-----1-----            java.lang.ClassLoader cl = packageInfo.getClassLoader();            service = packageInfo.getAppFactory()                    .instantiateService(cl, data.info.name, data.intent);        } catch (Exception e) {            if (!mInstrumentation.onException(service, e)) {                throw new RuntimeException(                    "Unable to instantiate service " + data.info.name                    + ": " + e.toString(), e);            }        }        try {            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);            //-----2-----            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);            //-----3-----            context.setOuterContext(service);            //-----4-----            Application app = packageInfo.makeApplication(false, mInstrumentation);            //-----5-----            service.attach(context, this, data.info.name, data.token, app,                    ActivityManager.getService());            //-----6-----            service.onCreate();            mServices.put(data.token, service);            try {                ActivityManager.getService().serviceDoneExecuting(                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);            } catch (RemoteException e) {                throw e.rethrowFromSystemServer();            }        } catch (Exception e) {            if (!mInstrumentation.onException(service, e)) {                throw new RuntimeException(                    "Unable to create service " + data.info.name                    + ": " + e.toString(), e);            }        }    }
  • 注释1处创建一个service对象。

  • 注释2处创建一个Service的ContextImpl对象。

  • 注释3setOuterContext将service对象赋值给ContextImpl中的mOuterContext, 这样ContextImpl就可以访问service中的方法和变量了。

  • 注释4处创建一个Application,在前面Android深入理解Context讲过。

  • 注释5处调用service.attach,将创建的context传递进service中。

  • 注释6处调用service.onCreate()

  • 我们主要看下注释4的代码部分,进入service.attach

    public abstract class Service extends ContextWrapper {    @UnsupportedAppUsage    public final void attach(            Context context,            ActivityThread thread, String className, IBinder token,            Application application, Object activityManager) {        attachBaseContext(context);        mThread = thread;           // NOTE:  unused - remove?        mClassName = className;        mToken = token;        mApplication = application;        mActivityManager = (IActivityManager)activityManager;        mStartCompatibility = getApplicationInfo().targetSdkVersion                < Build.VERSION_CODES.ECLAIR;    }}public class ContextWrapper extends Context {    protected void attachBaseContext(Context base) {        if (mBase != null) {            throw new IllegalStateException("Base context already set");        }        mBase = base;    }}
  • 最终还是将Service类型的ContextImpl赋值给了ContextWrapper中的mBase变量,这样我们调用ContextWrapper中的方法实际就是调用mBase这个真正的ContextImpl中的方法。

  • 至此我们关于Service的Context的分析就结束了。

更多相关文章

  1. Android高手进阶教程(十七)之---Android中Intent传递对象的两种
  2. Android中将资源文件转为Bitmap对象
  3. 面向UDP的Android——PC双向通信(三):在Android客户端和PC服务器端
  4. Android调用WebService系列之KSoap2对象解析
  5. Android Application对象必须掌握的七点
  6. android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入S
  7. Android判断网络状态是否断开+Android完全关闭应用程序+ 本文讲
  8. Android NDK 学习之传递类对象
  9. Android根据上下文对象Context找到对应的Activity

随机推荐

  1. 分享一下如何利用 Python测试 完成验签操
  2. 与孩子一起读古诗,是为了什么?
  3. 互动网站建设,如何操作,海量模板一站式建站
  4. Mac上复制和粘贴的一些小技巧
  5. 获取当天最大或最小日期
  6. java获取指定年月的开始时间与结束时间
  7. 以 DEBUG 方式深入理解线程的底层运行原
  8. 所谓 ICMP,不过将军与士卒而已
  9. 「跬步千里」详解 Java 内存模型与原子性
  10. Django 静态文件模板路径配置