概述
在Android应用进程中,每个应用都对应着一个Application。Application的创建于销毁贯穿了整个应用进程的生命周期。所以理解Application的创建过程不仅有利于我们理解应用进程的创建,还能加深对使用Application中的理解。
接下来回从两个进程中来分析Application的创建过程,一个进程是system_server进程,一个是应用进程。这两个进程都在创建的过程中创建了Application。
Application有什么用
我们使用Application一般是在应用进程中使用的。这里先列举下Application的经常用到的场景与职能。
- 处理应用程序生命周期;通过直接继承Application类,我们可以使用Application的生命周期方法来管理应用进程的生命周期,比如在onCreate()方法中初始化全局资源。
- 监听Activity生命周期;通过registerActivityLifecycleCallbacks()方法可以注册回调接口监听Activity的生命周期调用。
- 监听所有组件的回调方法;通过registerComponentCallbacks()方法实现,可以回调Android四大组件的公共方法,常用的有onConfigurationChanged(),onLowMemory()等。
- 通过Application获取应用资源
system_server中的创建过程
system_server进程是在Android系统启动时创建的一个进程,它的主要作用是启动和管理系统服务,比如我们熟知的AMS、WMS等。
接下来就分析下system_server创建Application的过程以及Application在system_server中起到的作用。
SystemServer的启动方法
system_server的启动是从run()方法开始的。
private void run() {
...
// Initialize the system context.
createSystemContext();
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
}
在run()方法中可以看到通过createSystemContext()方法创建了SystemContext。
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
在createSystemContext()方法中看到了一个熟悉的类ActivityThread。也就是Android主线程的启动类。我们可以看到调用过ActivityThread的systemMain()方法后,获取到了所谓的System Context。
接下来我们把目光转移到ActivityThread中去。
ActivityThread的systemMain()方法
public static ActivityThread systemMain() {
...
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
在ActivityThread的systemMain()方法中调用了attach()方法
private void attach(boolean system, long startSeq) {
...
if (!system) {
...
} else {
...
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo); // 1.创建ContextImpl
// 创建Application
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
需要注意的是,在attch()方法中有一个system的标志来区分system_server进程和应用进程。在systemMain()方法中调用attach()方法时system为true。所以我们直接看这个逻辑分支里的代码。
在开始创建Application前还有些准备工作:
- 创建了Instrumentation对象,用于之后的Application创建;
- 创建了SystemContext,在创建SystemContext时创建了LoadApk对象;
- 创建一个ContextImpl用来创建Application;
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
String opPackageName) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null, opPackageName);
context.setResources(packageInfo.getResources());
return context;
}
ContextImpl的createAppContex()方法用来生成一个ContextImpl实例,并且传递了ActivityThread、LoadedApk、opPackageName等参数。
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null, null);
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
创建SystemContext的过程中创建了LoadedApk实例。其中LoadedApk是与Application一一对应的。
接下开始了Application的创建过程,从LoadedApk的makeApplication()方法开始。
LoadedApk的makeApplication()方法
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
...
return app;
}
在开始创建Application的过程中LoadedApk的主要工作是先创建了一个ClassLoader用于接下来的创建流程,然后创建流程有来到了Instrumentation中。
Instrumentation的newApplication()
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
在这里通过反射创建了Application实例。
至此,在system_server中的创建过程就已结束。
应用进程中的创建过程
应用进程是从ActivityThread中的main()方法开始的
public static void main(String[] args) {
...
ActivityThread thread = new ActivityThread();
thread.attach(false);
...
}
在这里可以看到依然调用了attach()方法,不同的是system表示是false。接下来就分析下另外一个逻辑分支。
attach()方法的另外一种逻辑
private void attach(boolean system, long startSeq) {
...
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {}
...
}
在这里我们看到流程进入了AMS中attachApplication()
AMS中的创建过程
如果继续跟代码,就可以发现在attachApplicationLocked()方法中有调用了ActivityThread的bindApplication。这个过程是通过Binder方式进行通信的。
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
..
}
ActivityThread的bindApplication()
public final void bindApplication(...) {
...
sendMessage(H.BIND_APPLICATION, data);
...
}
在这里通过Handler发送BIND_APPLICATION的消息完成了Application的创建。
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
Process.setArgV0(data.processName);//
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
...
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);
mInstrumentation.callApplicationOnCreate(app);
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
在handleBindApplication()方法中创建Application的过程就跟system_server进程中创建的过程大同小异了。
总结
应用进程的Application创建过程,跟system进程的核心逻辑都差不多。只是app进程多了两次binder调用。