现在网上有很多文章都在介绍如何启动一个Activity,但是基本上很少介绍当要启动的App进程不存在的时候,是怎么启动进程,又是如何启动Activity的,那这篇文章就是来看看如何启动进程启动Activity的,希望不要翻车,这里特别说明下面的代码是Android 7.0的源码,其它Android源码有些类或者方法找不到。
首先我们无论是在Launcher中启动或者在App内部启动一个Activity,都会执行到ActivityStackSupervisor.startSpecificActivityLocked()方法
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
// 判断进程是否存在,存在就执行realStartActivityLocked方法
if (app != null && app.thread != null) {
//省略一些代码
...
// 启动Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
//省略一些代码
....
}
// 进程不存在,调用ActivityManagerService的startProcessLocked方法启动新进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
假如进程不存在,就会返回到ActivityManagerService启动新的进程
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
// 省略一些代码
.....
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
// 省略一些代码
.....
}
经过内部重载调用,走到这里,业务逻辑并不复杂,做一些调试标志位的设置什么的,就开始调用了Process的start方法。
Process的start方法会调用startViaZygote()方法
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
// 省略一些代码
.......
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
这里也没有太多的业务逻辑,只是做了些配置,然后调用zygoteSendArgsAndGetResult方法,方法的第一个参数来自openZygoteSocketIfNeeded,返回一个socket;从这里我们就可以发现,其实这里是通过socket通信的
这里的socket是在Zygote进程启动,我们可以在ZygoteInit的main方法中看到
public static void main(String argv[]) {
//省略代码
.......
registerZygoteSocket(socketName);
// 这里已经写好注释了,用于接受socket连接命令
Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList);
//省略代码
.......
}
在runSelectLoop方法中会调用ZygoteConnection的runOnce方法
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
// 省略部分代码
.......
try {
if (pid == 0) {
// in child
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// should never get here, the child is expected to either
// throw ZygoteInit.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
开启应用时,这里的pid是0会调用handleChildProc方法,handleChildProc方法中RuntimeInit.zygoteInit方法,在此方法中又会调用applicationInit方法,有转到invokeStaticMain方法,其实这个方法最后会抛出一个异常
public static class MethodAndArgsCaller extends Exception
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);
}
}
}
抛出一样,一直到ZygoteInit的main才被catch掉,然后运行run方法,就导致应用的ActivityThread.main方法执行。
在ActivityThread.main方法里面创建完ActivityThread实例后,会调用attach方法。
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
在这里,又回到了ActivityManagerService,attachApplication方法最终会调用attachApplicationLocked方法,在这里除去调用bindAppliaction,创建Application,还调用了ActivityStackSupervisor的attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked();
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}
这个方法有再次调用了realStartActivityLocked用于启动Activity。
ActivityStackSupervisor->ActivityManagerService:startProcessLocked(.)
ActivityManagerService->ActivityManagerService:startProcessLocked(..)
ActivityManagerService->Process:start()
Process->Process:startViaZygote()
Process->Process:zygoteSendArgsAndGetResult()
Process->ZygoteInit:socket
ZygoteInit->ZygoteInit:runSelectLoop()
ZygoteInit->ZygoteConnection:runOnce()
ZygoteConnection->ZygoteConnection:handleChildProc()
ZygoteConnection->RuntimeInit:zygoteInit()
RuntimeInit->RuntimeInit:applicationInit()
RuntimeInit->RuntimeInit:invokeStaticMain()
RuntimeInit->ActivityThread:main()
ActivityThread->ActivityThread:attach()
ActivityThread->ActivityManagerService:attachApplication()
ActivityManagerService->ActivityManagerService:attachApplicationLocked()
ActivityManagerService->ActivityStackSupervisor:attachApplicationLocked()
ActivityStackSupervisor->ActivityManagerService:realStartActivityLocked()