本文源代码基于 Android 7.0。
system 进程和 app 进程都运行着一个或多个 app,每个 app 都会有一个对应的 Application 对象 (该对象和 LoadedApk 一一对应)。今天就来分析一下 Application 的创建过程,其实前面的文章已经有大体讲过,这边单独抽出一章来系统讲解下。
目录:
- system_server 进程创建 Application
- app 进程创建 Application
1. system_server 进程创建 Application
- 1.1 SystemServer.createSystemContext():
/base/services/java/com/android/server/SystemServer.java
main() 方法中会调用 createSystemContext():
/**
* 理解Application创建过程已介绍过createSystemContext()过程, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application。
*/
private void createSystemContext() {
// 创建system_server进程的上下文信息
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
// 设置主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}
- 1.2 ActivityThread
/base/core/java/android/app/ActivityThread.java
public final class ActivityThread {
//创建ApplicationThread对象
final ApplicationThread mAppThread = new ApplicationThread();
final Looper mLooper = Looper.myLooper();
final H mH = new H();
//当前进程中首次初始化的app对象
Application mInitialApplication;
final ArrayList<Application> mAllApplications;
//标记当前进程是否为system进程
boolean mSystemThread = false;
//记录system进程的ContextImpl对象
private ContextImpl mSystemContext;
final ArrayMap<String, WeakReference<LoadedApk>> mPackages;
static Handler sMainThreadHandler;
private static ActivityThread sCurrentActivityThread;
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
}
其中 mInitialApplication 的赋值过程分两种场景:
- system_server 进程是由 ActivityThread.attach() 过程赋值;
- 普通 app 进程是由是由 ActivityThread.handleBindApplication() 过程赋值;
- 这是进程刚创建后 attach 到 system_server 后,便会 binder call 到 app 进程来执行该方法。
ActivityThread.currentApplication 返回的便是 mInitialApplication 对象。创建完 ActivityThread 对象,接下来执行 attach() 操作。
private void attach(boolean system) {
sCurrentActivityThread = this;
// 设置 mSystemThread 为 true
mSystemThread = system;
if (!system) {
...
} else {
// system 进程才执行该流程
// 创建 Instrumentation
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
// 回调 onCreate 方法
mInitialApplication.onCreate();
// ...
}
}
- 1.3 ContextImpl.createAppContext()
/base/core/java/android/app/ContextImpl.java
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread,
packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
根据 LoadedApk 对象来创建 ContextImpl,对于 system 进程 LoadedApk 对象取值为 mSystemContext,初始化 Application 信息。
- 1.4 LoadedApk
/base/core/java/android/app/LoadedApk.java
public final class LoadedApk {
private final ActivityThread mActivityThread;
private ApplicationInfo mApplicationInfo;
private Application mApplication;
final String mPackageName;
private final ClassLoader mBaseClassLoader;
private ClassLoader mClassLoader;
LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread; //ActivityThread对象
mApplicationInfo = new ApplicationInfo(); //创建ApplicationInfo对象
mApplicationInfo.packageName = "android";
mPackageName = "android"; //默认包名为"android"
...
mBaseClassLoader = null;
mClassLoader = ClassLoader.getSystemClassLoader(); //创建ClassLoader
...
}
}
只有一个参数的 LoadedApk 构造方法只有 createSystemContext() 过程才会创建,其中 LoadedApk 初始化过程会创建ApplicationInfo 对象,且包名为"android"。 创建完 LoadedApk 对象,接下里创建 ContextImpl 对象。
- 1.5 ContextImpl 初始化
class ContextImpl extends Context {
final ActivityThread mMainThread;
final LoadedApk mPackageInfo;
private final IBinder mActivityToken;
private final String mBasePackageName;
private Context mOuterContext;
// 缓存 Binder 服务
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
private ContextImpl(ContextImpl container, ActivityThread mainThread, LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted, Display display, Configuration overrideConfiguration, int createDisplayWithId) {
mOuterContext = this; //ContextImpl对象
mMainThread = mainThread; // ActivityThread赋值
mPackageInfo = packageInfo; // LoadedApk赋值
mBasePackageName = packageInfo.mPackageName; //mBasePackageName 等于 “android”
...
}
}
首次执行 getSystemContext,会创建 LoadedApk 和 contextImpl 对象,接下来利用刚创建的 LoadedApk 对象来创建新的ContextImpl 对象。
- 1.6 makeApplication()
/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
//保证一个LoadedApk对象只创建一个对应的Application对象
if (mApplication != null) {
return mApplication;
}
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application"; //system_server进程, 则进入该分支
}
//创建ClassLoader对象
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//创建Application对象
Application app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
appContext.setOuterContext(app);
...
mActivityThread.mAllApplications.add(app);
mApplication = app; //将刚创建的app赋值给mApplication
...
return app;
}
- 1.6 getClassLoader()
/base/core/java/android/app/LoadedApk.java
public ClassLoader getClassLoader() {
synchronized (this) {
if (mClassLoader != null) {
return mClassLoader;
}
if (mPackageName.equals("android")) {
if (mBaseClassLoader == null) {
//创建Classloader对象
mClassLoader = ClassLoader.getSystemClassLoader();
} else {
mClassLoader = mBaseClassLoader;
}
return mClassLoader;
}
// 当包名不为"android"的情况
if (mRegisterPackage) {
ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
}
zipPaths.add(mAppDir);
libPaths.add(mLibDir);
apkPaths.addAll(zipPaths);
...
if (mApplicationInfo.isSystemApp()) {
isBundledApp = true;
//对于系统app,则添加vendor/lib, system/lib库
libPaths.add(System.getProperty("java.library.path"));
...
}
final String zip = TextUtils.join(File.pathSeparator, zipPaths);
//获取ClassLoader对象
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
libraryPermittedPath, mBaseClassLoader);
return mClassLoader;
}
}
- 1.7 Application
/base/core/java/android/app/Application.java
初始化:
// Application继承于ContextWrapper,装饰器模式,最终ContextWrapper里面调用ContextImpl实现,都是继承于Context
public class Application extends ContextWrapper implements ComponentCallbacks2 {
/** @hide */
// LoadedApk
public LoadedApk mLoadedApk;
public Application() {
super(null);
}
}
attach():
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
- 将新创建的 ContextImpl 对象保存到 Application 的父类成员变量 mBase;
- 将新创建的 LoadedApk 对象保存到 Application 的父员变量 mLoadedApk;
2. app 进程创建 Application
- 2.1 ActivityThread
/base/core/java/android/app/ActivityThread.java
main():
public static void main(String[] args) {
,,,
ActivityThread thread = new ActivityThread();
thread.attach(false);
,,,
}
这是运行在 app 进程,当进程由 zygote fork 后执行 ActivityThread 的 main() 方法。
attach():
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//初始化RuntimeInit.mApplicationObject值
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.attachApplication(mAppThread);
} else {
...
}
}
经过 Binder 调用,进入 system server 进程,执行 attachAppliaction 操作。
- 2.2 ActivityManagerService
/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord
}
}
// ...
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
// ...
return true;
}
system server 收到 attach 操作,然后再向新创建的进程执行 bindApplication(),里面会进入 ActivityThread,发送消息到 H,执行 handleBindApplication()。
- 2.3 ActivityThread
/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
Process.setArgV0(data.processName);//设置进程名
...
//获取LoadedApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
...
// 创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
...
try {
// 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
mInstrumentation.onCreate(data.instrumentationArgs);
//回调onCreate
mInstrumentation.callApplicationOnCreate(app);
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
在 handleBindApplication() 的过程中,会同时设置以下两个值:
- LoadedApk.mApplication
- ActivityThread.mInitialApplication
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
if (differentUser) {
// Caching not supported across users
ref = null;
} else if (includeCode) {
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (packageInfo == null || (packageInfo.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) {
// 创建LoadedApk对象
packageInfo =
new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader());
}
if (differentUser) {
} else if (includeCode) {
// 将新创建的LoadedApk加入到mPackages
mPackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
}
}
return packageInfo;
}
}
创建 LoadedApk 对象,并将将新创建的 LoadedApk 加入到 mPackages。也就是说每个 app 都会创建唯一的 LoadedApk 对象,
此处 aInfo 来源于 ProcessRecord.info 变量,也就是进程中的第一个 app。
最后
以上就是壮观小霸王最近收集整理的关于Framework篇 - Application 的创建过程分析的全部内容,更多相关Framework篇内容请搜索靠谱客的其他文章。
发表评论 取消回复