源码阅读--应用上下文环境Context
来源:互联网 发布:加工中心手机编程软件 编辑:程序博客网 时间:2024/05/22 01:36
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对象
- 源码阅读--应用上下文环境Context
- 获取上下文环境context
- librealsense context 上下文环境
- Context 上下文 或者叫 环境
- org.tinygroup.context-上下文环境
- org.tinygroup.context-上下文环境
- 关于web应用上下文Context
- Android Context应用上下文详解
- 关于web应用上下文Context
- Context上下文的一些应用
- golang context 源码阅读
- Device Context 设备环境 设备上下文 理解
- Device Context 设备环境 设备上下文 理解
- Device Context 设备环境 设备上下文 理解
- 安卓 Context 上下文+应用共享概括
- [转]Android Context应用上下文详解
- 操作系统重点双语阅读 - 上下文切换 Context Switch
- Context(上下文)
- 两个listbox实现选项的添加删除和搜索
- 推荐支持AZW3和mobi格式的阅读器:FBReader
- HTTP死亡之旅:微信公众平台接口不再支持HTTP
- 基于thinkphp3.23源代码剖析
- 每日掌握一个Linux命令 之 显示用户最近登录信息 last命令
- 源码阅读--应用上下文环境Context
- 02.JAVA并发编程-线程的使用-构建启动线程
- JavaScript实现DOM对象选择器
- Linux高级文本处理命令
- MyBatis 动态SQL
- ShadowsocksR一键安装脚本
- get和post的区别
- easyui filebox只选择Excel文件(.xls/.xlsx)
- java八大基本类型初始化