Android APP启动过程中应用代码的加载
APP启动过程
- zygote->ActivityThread过程略过
- ActivityThread main函数
attach->ActivityManagerNative获得AMS代理对象IActivityManager
->AMS attachApplication AMS attachApplication
ProcessRecord app对象在startProcessLocked函数中已经创建if (app == null) { checkTime(startTime, "startProcess: creating new process record"); app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
调用newProcessRecordLocked函数
- ActivityThread bindApplication函数
封装AppBindData调用handleBindApplication handleBindApplication
APPBindData中最重要的两个参数:appInfo(AppAplication对象,该对象在PMS启动的时候scan时候创建),compatInfo(CompatibilityInfo对象,描述APP启动时候一些环境信息,缩放、分辨率等类似信息)。data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
第一次尝试获得LoadedAPK信息,
private LoadedApk getPackageInfo(...) { ... packageInfo = new LoadedApk(this, aInfo, compatInfo, baseLoader, ...);
此时传进来的baseLoader为空,此时并未设置APP的class loader.
instrumentationName 为通过am instrument启动时候的参数,该方法用于启动一个Instrumentation测试,例子:adb shell am instrument -w com.le.tcauto.uitest.test/android.support.test.runner.AndroidJUnitRunner
因此执行以下代码,创建Instrumentation类(工具类,用处很大):
mInstrumentation = new Instrumentation();
创建Context,并创建该APP的Class Loader:
Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app;
makeApplication函数:
java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); }
getClassLoader函数:
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib, mBaseClassLoader);
其中zip和lib的位置,是由LoaderAPK的mAppDir和mLibDir设置,这两个变量是LoadedAPK构造函数中ApplicationInfo对象获得的,ApplicationInfo中该成员变量则是在PMS启动时候获得的。ApplicationLoaders中根据zip和lib构造出一个PathClassLoader对象。
initializeJavaContextClassLoader:ClassLoader contextClassLoader = (sharable) ? new WarningContextClassLoader() : mClassLoader; Thread.currentThread().setContextClassLoader(contextClassLoader);
将该class loader设进当前进程。