APP进程启动流程
当用户点击桌面上的APP图标打开一个应用,这中间发生了什么?桌面通过Intent启动APP之后系统做了哪些?Android系统做了非常复杂的操作。从全局流程上简化来看,在上次分析的Zyoget进程的启动流程中,了解到通过AMS发送启动应用的请求,Zygote服务端接收到请求后,fork自己创建应用程序进程。
1、启动APP
点击桌面上的图标启动应用的时候和通过Intent启动Activity一样,接着Activity启动流程源码分析一文执行到ActivityStackSupervisor类中startSpecificActivityLocked()方法继续分析,这里会判断应用是否已经有进程,新启动的应用没有进行需要创建APP进程。
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 该活动的应用程序已经在运行吗?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// 如果抛出了死对象异常,请重新启动应用程序。
knownToBeDead = true;
}
// 禁止过渡,直到新活动准备就绪为止,
// 否则在新活动的新进程可以设置其showWhenLocked标志的能力之前,键盘锁可能会出现一小段时间。
if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
// 发布消息以启动过程,以避免在保持ATMS锁定的情况下呼叫AMS的死锁。
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}2、需要创建进程
如果启动的APP进程不存在,则需要先启动应用进程。这里的方法和之前源码大不相同,基本上已经很难继续跟下去。并非直接调用mService的startProcessLocked()方法,而是通过Message和Handler间接触发:
...
// 发布消息以启动过程,以避免在保持ATMS锁定的情况下呼叫AMS的死锁。
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
...com.android.internal.util.function.pooled.PooledLambda类的obtainMessage(...)方法有非常多的重载,主要是参数个数不同:第一个传入的参数function,后面这些参数都是作为调用function的参数。
static <A, B, C, D, E, F, G> Message obtainMessage(
HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}不要怀疑为什么找不到调用的acquire(...)方法,是通过static关键字静态导入的方法,
import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire;
...定义在PooledLambdaImpl的acquire(...)方法。
/**
* 内部非类型安全工厂方法
*/
static <E extends PooledLambda> E acquire(Pool pool, Object func,
int fNumArgs, int numPlaceholders, int fReturnType, Object a, Object b, Object c,
Object d, Object e, Object f, Object g, Object h, Object i) {
PooledLambdaImpl r = acquire(pool);
...
r.mFunc = Preconditions.checkNotNull(func);
r.setFlags(MASK_FUNC_TYPE, LambdaType.encode(fNumArgs, fReturnType));
r.setFlags(MASK_EXPOSED_AS, LambdaType.encode(numPlaceholders, fReturnType));
if (ArrayUtils.size(r.mArgs) < fNumArgs) r.mArgs = new Object[fNumArgs];
setIfInBounds(r.mArgs, 0, a);
setIfInBounds(r.mArgs, 1, b);
setIfInBounds(r.mArgs, 2, c);
setIfInBounds(r.mArgs, 3, d);
setIfInBounds(r.mArgs, 4, e);
setIfInBounds(r.mArgs, 5, f);
setIfInBounds(r.mArgs, 6, g);
setIfInBounds(r.mArgs, 7, h);
setIfInBounds(r.mArgs, 8, i);
return (E) r;
}返回的PooledRunnable接口类型:
public interface PooledRunnable extends PooledLambda, Runnable, ThrowingRunnable {
/** @inheritDoc */
PooledRunnable recycleOnUse();
}返回Runnable对象,设置给Message,这个Runnable在Message中的定义说明:callback Runnable that will execute when the message is handled。当Message被Handler处理的时候会执行。
回到ActivityStackSupervisor中的startSpecificActivityLocked()方法中,之后向mService的mH发送上面构造好的Message,mService是ActivityTaskManagerService,其中的成员变量mH是静态内部类:
final class H extends Handler {
static final int REPORT_TIME_TRACKER_MSG = 1;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_SUPERVISOR_STACK_MSG = 200;
H(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REPORT_TIME_TRACKER_MSG: {
AppTimeTracker tracker = (AppTimeTracker) msg.obj;
tracker.deliverResult(mContext);
} break;
}
}
}还没有摸清楚怎么构造这个Runnable的,但是可以确定是执行传入的function,也就是抽象类ActivityManagerInternal的startProcess()抽象方法。ActivityManagerInternal类的实现在哪里呢?
错综复杂的Android源码,想找到一个抽象类的实现在哪里是非常的困难。千万不要自己摸索,太浪费时间,直接搜索博客资料,立马豁然开朗。
3、AMS发起创建进程请求
ActivityManagerInternal类的实现就是熟悉的AMS:ActivityManagerService,关于AMS的启动见AMS服务的启动一文。
public final class LocalService extends ActivityManagerInternal {
...
}内部LocalService类继承ActivityManagerInternal类并且实现所有的方法:
@Override
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}startProcess()方法实现中调用了startProcessLocked(...)方法
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}mProcessList是ProcessList类型对象,调用它的startProcessLocked(...)方法(注意该方法也有很多重载)
boolean startProcessLocked(HostingRecord hostingRecord,
String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
app.pendingStart = true;
app.killedByAm = false;
app.removed = false;
app.killed = false;
...
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
...
} else {
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
invokeWith, startTime);
...
}
}调用startProcess(...)方法:
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
...
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
...
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}4、Zygote机制请求
最后调用Process的start(...)方法,进入新的一个阶段:
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs);
}ZYGOTE_PROCESS是定义在Process类中ZygoteProcess类型的的成员变量:
/**
* State associated with the zygote process.
* @hide
*/
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();调用ZygoteProcess的start(...)方法:
/**
* Start a new process.
*/
public final Process.ProcessStartResult start(...) {
...
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, useUsapPool, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
...
}
}调用startViaZygote(...)方法:
/**
* Starts a new process via the zygote mechanism.
*/
private Process.ProcessStartResult startViaZygote(...) throws ZygoteStartFailedEx {
...
synchronized(mLock) {
// 如果应用程序不使用系统图形驱动程序,则不能使用USAP池。
// 如果要求该驱动程序,请使用Zygote应用程序启动路径。
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useUsapPool,
argsForZygote);
}
}参数中调用了openZygoteSocketIfNeeded(abi)方法:
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
attemptConnectionToPrimaryZygote();
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
attemptConnectionToSecondaryZygote();
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}原来的代码是一个方法,现在进行了拆分:该方法中调用了两个方法attemptConnectionToPrimaryZygote()和attemptConnectionToSecondaryZygote(),都是尝试连接Zygote主模式/辅模式。
回到主流程,继续调用zygoteSendArgsAndGetResult(...)方法,原来的代码是一个方法,现在进行了拆分:
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
...
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}继续调用attemptUsapSendArgsAndGetResult(...)或者attemptZygoteSendArgsAndGetResult(...)方法
private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr)
throws ZygoteStartFailedEx, IOException {
...
Process.ProcessStartResult result = new Process.ProcessStartResult();
...
if (result.pid >= 0) {
return result;
} else {
throw new ZygoteStartFailedEx("USAP specialization failed");
}
}获取Zygote中创建的结果ProcessStartResult。
5、Zygote接收并创建进程
接着上次Zygote进程的启动,看看Zygote是如何处理AMS的请求并创建进程的。回到ZygoteInit的main方法
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
...
try {
...
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
} finally {
}
...
}ZygoteServer类中的runSelectLoop()方法等待AMS请求创建新的APP进程,简化之后如下:
Runnable runSelectLoop(String abiList) {
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
...
while (true) {
...
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
...
}
}
}调用ZygoteConnection的processOneCommand()方法:处理AMS的请求数据,fork当前进程创建应用程序进程。
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
try {
args = Zygote.readArgumentList(mSocketReader);
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
...
//在这里创建APP进程
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// 在父进程中, pid <0表示失败,将在handleParentProc中进行处理。
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
}其中返回了handleChildProc(),当pid为0的时候,代码运行在当前新创建的进程,调用该方法来处理APP:
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
/**
* 到我们到达这里时,本机代码已关闭两个实际的Zygote套接字连接,
* 并在其位置替换了/ dev / null。 LocalSocket对象仍然需要正确关闭。
*/
closeSocket();
...
if (parsedArgs.mInvokeWith != null) {
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.mRemainingArgs);
// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}方法结尾处调用ZygoteInit的zygoteInit(...)方法:
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}该方法主要做了两件事情:
①nativeZygoteInit():创建应用程序的Binder线程池。
private static final native void nativeZygoteInit();②RuntimeInit.applicationInit(...):反射查找调用main()方法。
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args = new Arguments(argv);
...
return findStaticMain(args.startClass, args.startArgs, classLoader);
}找到main()方法调用并返回,之前的源码是封装成异常直接throw回到Zygote的mian()方法中(为了清除堆栈帧,现在不这样做了)
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
...
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
return new MethodAndArgsCaller(m, argv);
}回到ZygoteInit的main方法,这时候已经在APP进程并非原来的Zygote进程,将返回的Runnable对象调用并执行:
@UnsupportedAppUsage
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
...
// 我们在子进程中,已经退出选择循环。 继续执行命令。
if (caller != null) {
caller.run();
}
}MethodAndArgsCaller是定义在RuntimeInit中的静态内部类:
/**
* Helper class which holds a method and arguments and can call them. This is used as part of
* a trampoline to get rid of the initial process setup stack frames.
*/
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}其中调用mMethod的invoke()反射方法,其实就是ActivityThread的main()静态方法,APP进程进入了ActivityThread的main方法开始执行,由ActivityThread管理APP进程。
相关博客:
Android App 启动流程梳理(基于 Android 10)

