前言
本篇继续探索oat文件的加载。先补充些内容:
ApplicationThread与Application不同。
ActivityThread内mAppThread是一个ApplicationThread类型的Binder对象,它的作用是用来进行进程间通信的。其继承于IApplicationThread.Stub
Application是继承ContextWrapper的组件,表示app,同样存于ActivityThread内mInitialApplication全局唯一
参考文:
http://gityuan.com/2017/04/09/android_context/
https://shuwoom.com/?p=142
几个关键的类:
- ActivityThread:主线程,通过接受AMS的请求对Activity等组件进行控制。因此可以及时控制app。
- Application:代表app对象,LoadedApk对象存于其中。
- Instrumentation:用来监控系统和应用的交互常用于测试。
- LoadedApk:当前加载的APK包的各种信息
图
有些类的调用比较多因此省略图,但在文中会有体现
源码
1-handleBindApplication
handleBindApplication
frameworks\base\core\java\android\app\ActivityThread.java
instrumentation是一种典型的委托观察者模式,用该对象操作活动等可以检测活动。
其常用于测试,可在manifest文件中声明,定义。
从上到下依次看:
2-getPackageInfoNoCheck
创建LoadedApk:
frameworks\base\core\java\android\app\ActivityThread.java
mPackages的数据类型为ArrayMap
当mPackages没有找到相应的LoadedApk对象, 则创建该对象并加入到mPackages。这里初次创建。
4-LoadedApk
LoadedApk
frameworks\base\core\java\android\app\LoadedApk.java
对象的属性赋予。baseLoader为null
一个应用程序对应一个LoadedApk对象。它用来保存当前加载的APK包的各种信息,包括app安装路径、资源路径、用户数据保存路径、使用的类加载器、Application信息等。
!!这几个值需要打印下看下具体路径!!
Instrumentation
默认的Instrumentation:
都是空….因为是测试类要实现的,用于在正常回调前执行。
7-makeApplication
data.info.makeApplication
frameworks\base\core\java\android\app\LoadedApk.java
LoadedApk中存有应用解析出的各种信息。这里获取ClassLoader、创建ContextImpl对象、创建Application对象并attach。
顺路把createAppContext看一下
frameworks\base\core\java\android\app\ContextImpl.java
到此为止简单总结下Context是什么。通过其使用与构造可以看出就是如其所意:上下文,存储着运行环境的相关信息。并设定其运行场景可执行的不同方法。
ContextImpl:
Application/Activity/Service通过attach() 调用父类ContextWrapper的attachBaseContext(), 从而设置父类成员变量mBase为ContextImpl对象;
ContextWrapper的核心工作都是交给mBase(即ContextImpl)来完成;
13-newApplication
mInstrumentation.newApplication
frameworks\base\core\java\android\app\Instrumentation.java
通过classloader加载类创建对象。
frameworks\base\core\java\android\app\Application.java
- 将新创建的ContextImpl对象保存到Application的父类成员变量mBase;
- 将当前所在的LoadedApk对象保存到Application的父员变量mLoadedApk;
保护时常重写attachBaseContext方法!!!!!!!
9-createOrUpdateClassLoaderLocked
getClassLoader
frameworks\base\core\java\android\app\LoadedApk.java
在这里mClassLoader为null,第三方应用且includecode为true,经过判断各项包的属性进入:
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,libraryPermittedPath, mBaseClassLoader);
10-getClassLoader
frameworks\base\core\java\android\app\ApplicationLoaders.java
从缓存中获取,没有的话就新建并添加缓存,parent为默认创建的PathClassLoader
11-createClassLoader
createClassLoader
frameworks\base\core\java\com\android\internal\os\PathClassLoaderFactory.java
正式创建PathClassLoader就在这里。
15-callApplicationOnCreate
frameworks\base\core\java\android\app\Instrumentation.java
后记
android架构逐渐明朗,ActivityThread受到AMS的BindApplication命令后,用AMS传来的应用信息创建LoadedApk,application,Instrumentation等单例对象。
重点放在classloader的创建和类查找执行上,下一篇进入classloader。