[置顶] 源码阅读--应用上下文环境Context
2017-09-30 09:57
459 查看
Context上下文环境包括哪些
Context继承结构android应用是基于组件的,四大基本应用组件构成了基本的应用。开放给开发者的应用组件,打个比方就像一栋建筑的每个房间,我们像搭积木一样把每个房间合理摆放组成一栋建筑,但是现实中建筑并不是房间的简单堆砌,还要有地基,还要有钢筋结构的连接,有水电管线,有物业管理等配套的服务设施。同样的应用组件也要有运行的配套环境,这些环境在Context中进行了定义。
1.先看一下Context类的注释
Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.
提供应用环境的全局信息的接口,可以获取到应用自有的资源和class类,同时应用层级操作(启动activity,发送广播等)
看一下Context源码中的方法定义:上图罗列了部分方法定义getResources()、getDrawable()、getClassLoader()是获取到应用自有的资源和class类相关的方法,此外有startActivity()等方法进行组件级操作。
2.此外,还有一些对数据文件的操作:sp,文件,数据库;方法getSystemService()提供了获取系统服务的能力
总结一下,Context提供了以下应用上下文环境:
1.应用自有资源与代码
2.组件操作(组件启动,广播,Receiver注册等)
3.数据IO操作
4.系统服务获取
5.主线程关联
Context的结构设计采用了装饰者模式。Activity,Service和Application都直接或间接继承自ContextWrapper,这三个类很少对ContextWrapper方法进行重写(Activity处理较多),对而ContextWrapper把所有功能都委托给ContextImpl来实现,Context的基础功能基本上都在ContextImpl中实现。
资源管理与代码加载
资源管理
以getDrawable为例,看一下Context如何获取资源文件:Context.java
public final Drawable getDrawable(@DrawableRes int id){ return getResources().getDrawable(id, getTheme()); }
ContextImpl.java
默认会调用LoadedApk的getResources方法获取Resources对象。
LoadedApk.java
ActivityThread.java
可以看出所有的Resources创建都汇集到ResourcesManager这个类来进行。ResourcesManager采用单例模式,也就是说同一进程下的Resources对象是由同一个ResourcesManager创建的。具体的资源管理会在后面分析。
代码加载
java类加载遵循双亲委托模型,android同样遵循该模型,只是在ClassLoader的继承结构上有差异。看一下ClassLoader的创建:ContextImpl.java
LoadedApk.java
在createOrUpdateClassLoaderLocked方法中,调用了ApplicationLoader的getClassLoader方法:
可以看到这里ClassLoader是PathClassLoader对象。
看一下PathClassLoader类的注释,
Android uses this class for its system class loader and for its application class loader(s).
这个类加载器用于加载安卓系统类和应用程序类,这里的应用必须是已安装的。这也说明上面的ClassLoader对象是PathClassLoader对象。
更多ClassLoader信息参考:Android动态加载之ClassLoader详解
LoadedApk
从前面可以看出,资源和代码的管理都用到了LoadedApk这个类。在ActivityThread类中,提供了获取LoadedApk对象的方法
LoadedApk.java
loaded描述了一个已加载的apk的状态。下图展示了LoadedApk的主要成员,包括apk位置,资源目录,数据目录等,最主要的是ApplicationInfo,可以看到主要成员的设置跟ApplicationInfo是相关的。
数据操作
安卓的数据存储包括SharedPrefereces,File,DataBase,网络等方式,Context提供了部分数据源API包括Sp,File,DataBase。Sp
Sp数据以xml文件形式存储在data/data/<包名>/preferens目录下。Context提供getSharedPreferences方法返回SharedPreferencesImpl对象File
Context提供openFileInput和openFileOutput用于处理文件这里的文件默认是位于data/data/<包名>/files目录下的。sd卡目录可以通过Environment.getExternalStorageDirectory()获取。Context也提供了一些Api获取sd卡目录,也是通过Environment
Database
Context提供openOrCreateDatabase创建数据库,但数据库相关操作一般是使用SQLiteOpenHelper系统服务
Context定义了一系列Service常量名,可以通过getSystemService(String name)获取对应服务。Context创建
Context使用了装饰这模式,Application等Context子类对象其实是封装了ContxetImpl的实现,通过持有的mBase对象(ContextImpl)实现具体操作。那么封装类和mBase是在什么时候关联的?Application的创建
在应用进程启动以后,应用通过ActivityThread的main方法开始执行,先会bindApplication与AMS交互,在回调处理中会触发handleBindApplication方法,Application对象在此时创建。Context关联
handleBindApplication
这里调用了LoadedApk的makeApplication方法
继续调用Instrumentation的newApplication
attach方法中调用了attachBaseContext在这里进行了Context关联
ContextImpl创建
在LoadedApk的makeApplication方法中调用了ContextImpl.createAppContext工厂方法。
ContextImpl类提供了三个静态工厂方法创建ContextImpl对象
LoadedApk是ContextImpl类中mPackageInfo的类型,一个重要成员。makeApplication中传入的参数是当前LoadedApk对象。再看一下前面makeApplication的调用
Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app;
这里的data.info就是一个LoadedApk对象,创建也是在handleBindApplication方法中。
data.info = getPackageInfoNoCheck(data.appInfo,data.compatInfo);
ActivityThread提供getPackageInfo方法创建LoadedApk对象
相关文章推荐
- [置顶] 源码阅读--package管理与应用安装
- [置顶] 源码阅读---Activity启动中应用进程的创建
- 使用IntelliJ IDEA配置Spark应用开发环境及源码阅读环境
- [置顶] nginx源码阅读(十).ngx_event_core_module模块
- Spring学习1:Spring源码阅读环境搭建
- NET2.0环境下的Ajax选型和应用(提供Demo源码下载)
- Spring与web MVC的整合——Spring的应用上下文管理 -- DispatcherServlet与ContextLoaderListener解释
- 建立Apache Geode源码阅读环境
- spring framework 4 源码阅读(2)---从ClassPathXmlApplicationContext开始
- 通过SpringContextUtil获取spring环境上下文
- OpenJDK源码研究笔记(十三):Javac编译过程中的上下文容器(Context)、单例(Singleton)和延迟创建(LazyCreation)3种模式
- 配置spark源码阅读windows环境
- Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程分析 .
- Spring5.0.X源码阅读环境搭建Eclipse4.6.3(neon)
- Scala深入浅出进阶经典 第45讲:Scala中Context Bounds代码实战及其在Spark中的应用源码解析
- Windows + IDEA + SBT 打造Spark源码阅读环境
- Linux下Web服务器应用之源码构建LAMP环境
- daily news新闻阅读客户端应用源码(兼容iPhone和iPad)