大家在应用程序开发的时候会经常遇到Context,也经常使用,那怎么理解Context呢?

在做Web开发的时候也会有一个Context,一般翻译“成上下文”,也就是代表整个程序运行的环境,直到进程结束之后。 那么Android中的Context是不是这样的呢?Android中不是,Android中的Context可以理解成场景,场景是什么什么意思呢? 如果把Android程序的整个运行期间成为一个电影的话,那么一个Activity或者一个Service就可以称之为一个场景,一个电影 可以包括多个场景。 咱们先看下Context相关的继承结构:

从继承关系可以看出,Activity和Service都是基于Context实现的。 Activity不仅基于Context实现,并且还实现了一些重要的其他接口。从设计的角度,继承的才是类的本质,接口仅仅是未来扩充功能。 Activity和Service本质是一个Context,然后扩充了一些功能之后,要么成为Activity,要么成为Service。 而Application也可以认为是为了做一些操作方便,才继承的Context。
也就是说有多少个Activity和Service就有多少个场景,也就是有多少个Context对象(Application也算一个)。
这个Context仅代表一个Activity或者一个Service(Application除外)。
Context的真正实现类是ContextImpl,ContextWraper根据名称可以看出是Context的包装类,在ContextWrap中包装 了ContextImpl,调用ContexWraper的时候也就调用到了ContextImpl的方法。ContextWraper提供了set ContextImpl 的方法attachBaseContext()。
Activity最终是包含界面的所以他继承了ContextThemeWraper,有Theme这个单词,这个Theme是AndroidMenifest.xml中 的Theme标签对应的Theme。因为Service和Application都不包含界面,就没必须继承ContextThemeWraper了,只需继承 ContextWraper即可。

Application对应的Context
每个应用程序在第一次启动的时候都会产生一个Application,这个Application在整个程序运行期间是唯一的,程序员们可以 根据自己程序的需要重写这个函数,只需继承一下,在需在AndroidMenifest.xml文件的<application>标签上配置下类全名即可, 不配置的话会使用默认的Application。(因为全局是唯一的,可以使用它做一些数据库缓存或者数据传递地方)。
程序第一次启动时,ActivityManagerService会经过ApplicationThread的代理类 远程调用真正的ApplicationThread的bindApplication()方法(这个里把ActivityManagerService当成了Binder客户端, 在ActivityThread中的ApplicationThread对象才是真正的Binder服务端)。
ApplicationThread这个类定义在ActivityThread类文件中。 代码片段1

这些参数都是从ActivityManagerService通过IPC(Binder方式)传递过来的。如果要在Binder方式中传递对象的话,那么这个类 要实现Parceable接口,看下第一个参数appInfo,通过名字可以知道,是代表应用程序的信息类,这个类按道理肯定实现了 Parceable接口,不错确实实现了这个接口。看下这个类的声明。 、、 代码片段2
还继承自PackageIntemInfo,PacageItemInfo就是通过AndroidMenifest.xml文件解析出的啊<application>标签中的内容 代码片段3
从547行开始看,此处创建了一个AppBindData对象data,然后把从ActivityManagerService远程传递过来的参数赋值给data对象, 其中第549行就包括了appInfo赋值给了data对象的appInfo。 咱们看看AppBindData类到底是什么样的,AppBindData是ActivityThread中的内部类。从下面的代码可以看出只是对传过来的参数进行 了简单的封装。 、 代码片段4 我们再回到 代码片段1 中的558行其中参数中H.BIND_APPLICATION是继承自Handler的一个类的一个int常量,第二个参数就是刚封装的数据类型data了。 继续代码
代码片段5

继续代码
代码片段6
重点就是what参数和obj参数。在1519行获得一个可回收利用的Message对象,然后把传递过来的消息发送到消息队列(1524行),‘ Looper一直在从消息队列里取消息。当取到刚发送的消息后,会回调Handler的handleMessage()方法,继续到H类中 先说明一下,ActivityThread创建时这个H的对象就已经创建好了,这个Handler属于UI线程(主线程)。 代码片段7 那咱们还是去H这个类的handleMessage()方法吧 其中有个switch结构 H.BIND_APPLICATION对相应的处理如下:
代码片段8 968行把msg中的obj强制转型成AppBindData,做为handleBindApplication(data)的参数继续执行
代码片段9 3122行,把data赋值给了mBoundApplication
代码片段10
3149行,调用getPacageInNocheck()构建一个LoadedApk对象,赋值给data.info。在这个调用中把LoadedApk对象存到了mPackages中。 这个LoadedApk对象,这个对象包含了更多的应用程序的信息。
代码片段11 第3260行才是真正的使用反射创建一个Application对象,返回值赋值给mInitialApplication。 进入到Loaded.makeApplication()方法,如下 代码片段12 454行:forceDefaultAppClass这个参数的意思是,是否强制使用系统提供的默认class类,即android.app.Application’ 459行:创建了一个ContextImpl实例 461行:创建了一个Application实例,mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext)的具体实现如下:
代码片段13
942行:继续调用重载的方法
代码片段14 第958行是设置Application和Context的关联。
调用完整个方法,继续回到 代码片段12中 463行设置Context和Application的关联。 片段12的代码继续执行到下面,把Application保存到LoadedApk中一份 代码片段14 这方法执行完成之后回到 代码片段11继续执行 代码片段15
在上面的方法中执行了Application的onCreat()方法 代码片段16
程序员可以重载Application的onCreate()知道Application创建后的时机,然后做一些相应的操作。
以上就是说明了Application和Context的关系
大致流程如下

没完,待续.....
Activity对应的Context
Service对应的Context

更多相关文章

  1. android 用inten传递对象
  2. Android(安卓)ORM框架GreenDao入门学习
  3. Android系统Intent的使用
  4. 【Android设备管理】 利用DevicePolicyManager执行屏幕锁定
  5. Android(安卓)如何全局获取Context
  6. android支付宝客户端html5网页偶尔无法自动关闭问题
  7. Android(安卓)中动态加载.jar的实现步骤
  8. Android最佳实践之:StrictMode介绍
  9. 再识Intent-实现调用Android内置浏览器打开网页

随机推荐

  1. android 一些小功能实现
  2. 跑马灯效果
  3. 编译cubieboard android 源码过程详解之(
  4. android 模拟器常用命令
  5. Android实现启动页停留几秒然后自动跳转
  6. android 硬解码 是否支持
  7. Android实现轮播图效果
  8. sqlite3 表结构查询
  9. android获取屏幕大小
  10. Fresco使用的注意事项