一. 前景
在Android中每个App在启动前必须先创建一个进程,该进程是由Zygote fork出来的,进程具有独立的资源空间,用于承载App上运行的各种Activity/Service等组件。进程对于上层应用来说是完全透明的,这也是google有意为之,让App程序都是运行在Android Runtime。大多数情况一个App就运行在一个进程中,除非在AndroidManifest.xml中配置Android:process属性,或通过native代码fork进程。 – 来自Gityuan
VA作为Android应用的容器框架,允许用户安装第三方应用到该容器中,需要为运行在其中的应用创建进程,然而VA也只是运行在Android系统中的一款普通的应用,不能像framework那样简单的通过Zygote fork进程来提供新启动的App的运行环境。所以需要有一套有效的机制来创建进程,并且分配给运行在VA中的应用使用。想要了解Android framework如何创建进程的同学可以查看理解Android进程创建流程,在这里不做过多研究。
二. 四大组件与VAppClient进程
当VA启动容器中的应用时,如果还未分配进程给该应用,那么在startProcessIfNeedLocked
方法中会为该应用启动并分配进程。
2.1. Activity
VA启动Activity时,调用startActivity
,最终会调到ActivityStack.java中的startActivityLocked
方法,根据不同的状态,分别执行startActivityInNewTaskLocked
,startActivityFromSourceTask
,在这两个方法中都会去调用startActivityProcess
方法。
deliverNewIntentLocked方法走的时Activity的onNewIntent逻辑,在这不做过多描述
ActivityStack.java
int startActivityLocked(int userId, Intent intent, ActivityInfo info, IBinder resultTo, Bundle options,
String resultWho, int requestCode) {
...
if (reuseTask == null) {
startActivityInNewTaskLocked(userId, intent, info, options);
} else {
...
if (clearTarget.deliverIntent || singleTop) {
...
if (topRecord != null && !topRecord.marked && topRecord.component.equals(intent.getComponent())) {
deliverNewIntentLocked(sourceRecord, topRecord, intent);
delivered = true;
}
}
...
if (!startTaskToFront) {
if (!delivered) {
destIntent = startActivityProcess(userId, sourceRecord, intent, info);
if (destIntent != null) {
startActivityFromSourceTask(reuseTask, destIntent, info, resultWho, requestCode, options);
}
}
}
}
return 0;
}
private Intent startActivityInNewTaskLocked(int userId, Intent intent, ActivityInfo info, Bundle options) {
Intent destIntent = startActivityProcess(userId, null, intent, info);
...
return destIntent;
}
private boolean startActivityFromSourceTask(TaskRecord task, Intent intent, ActivityInfo info, String resultWho,
int requestCode, Bundle options) {
ActivityRecord top = task.activities.isEmpty() ? null : task.activities.get(task.activities.size() - 1);
if (top != null) {
if (startActivityProcess(task.userId, top, intent, info) != null) {
realStartActivityLocked(top.token, intent, resultWho, requestCode, options);
return true;
}
}
return false;
}
private Intent startActivityProcess(int userId, ActivityRecord sourceRecord, Intent intent, ActivityInfo info) {
ProcessRecord targetApp = mService.startProcessIfNeedLocked(info.processName, userId, info.packageName);
...
}
2.2. Service
VA启动Service时,调用startService
或者bindService
,最终会调到VActivityManagerService.java的startServiceCommon
方法。
VActivityManagerService.java
private ComponentName