文化袁探索专栏——Activity、Window和View三者间关系
文化袁探索专栏——View三大流程#Measure
文化袁探索专栏——View三大流程#Layout
文化袁探索专栏——消息分发机制
文化袁探索专栏——事件分发机制
文化袁探索专栏——Launcher进程启动流程’VS’APP进程启动流程
文化袁探索专栏——Activity启动流程
文化袁探索专栏——自定义View实现细节
文化袁探索专栏——线程池执行原理|线程复用|线程回收
文化袁探索专栏——React Native启动流程
关于Launcher进程启动流程在研究过程中想到了,ta与APP进程启动流程有什么不同?
Launcher应用是我们的安卓应用桌面;APP是安装显示在桌面的ICON;他们统称第三方应用。所有的APP进程都有zygote fork生成。
粉色描述主流程:
当第一个Java进程Zygote被孵化后,会通过ZygoteInit.java在入口方法main(String argv[])孵化第一个安卓的系统服务进程SytemServer。并由此进入到了Android Framework层:
/// ZygoteInit.java/main方法
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
// 之后进入frokSystemServer方法中
/// ZygoteInit.java/frokSystemServer方法
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
安卓系统的第一个系统进程SytemServer被孵化并启动后,在ta的main方法中主要做了三件事情——启动不同类型的系统服务:
///SystemServer.java[Android API 30]
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer(){
//创建系统的服务的管理者
SystemServiceManager mSystemServiceManager = new SystemServiceManager(mSystemContext);
// Start services.
try {
t.traceBegin("StartServices");
startBootstrapServices(t); //启动引导服务
startCoreServices(t);//启动核心
startOtherServices(t);//启动其他一般服务
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
}
/// 当其他服务启动完毕后,且当ActivityManagerService服务启动后方法 mActivityManagerService.systemReady被调用,开启Launcher进程启动的第一步:
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
... ...
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
t.traceBegin("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
t.traceEnd();
... ...
}
当其他服务启动完毕后,且ActivityManagerService服务启动后,mActivityManagerService.systemReady被调用,开启Launcher进程启动的第一步:
///ActivityManagerService.java[Android API 30]
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
... ...
if (bootingSystemUser) {
t.traceBegin("startHomeOnAllDisplays");
//进入Launcher进程启动流程
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
}
}
执行方法mAtmInternal.startHomeOnAllDisplays
–>>ActivityTaskManagerService#LocalService.startHomeOnAllDisplays()
–>>RootWindowContainer.startHomeOnAllDisplays
–>>ActivityStartController.startHomeActivity
–>>ActivityStackSupervisor.scheduleResumeTopActivities
–>>RootWindowContainer.resumeFocusedStacksTopActivities
–>>ActivityStack.resumeTopActivityUncheckedLocked
–>>ActivityStack.resumeTopActivityInnerLocked
–>>ActivityStackSupervisor.startSpecificActivity
通过方法startSpecificActivity
中,判断要启动Activity所在进行控制器是否存在?
/// ActivityStackSupervisor.startSpecificActivity [Android API 30]
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
// 判断要启动Activity所在进行控制器是否存在?
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);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
// 创建进程
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
第一次启动进程进程控制器wpc必然为空,则执行mService.startProcessAsync
异步创建Launcher进程。
并将进程创建工作交由WindowManagerService.startProcess
–>>WindowMangerService.startProcessLocked
–>>ProcessList.startProcessLocked
/// ProcessList.java
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
boolean mountExtStorageFull, String abiOverride) {
...
final String seInfo = app.info.seInfo
+ (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
// 指定所有App应用进程入口类
final String entryPoint = "android.app.ActivityThread";
// 开始进行创建进程
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
...
}
/**之后执行方法*/
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
...
else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
// We can't isolate app data and storage data as parent zygote already did that.
// 真正进入fork Launcher进程
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
false, false,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
}
...
}
然后继续执行创建进程相应方法ZygoteProcess.start…ZygoteProcess.zygoteSendArgsAndGetResult,然后执行到方法ZygoteProcess.attemptUsapSendArgsAndGetResult时,进程创建最后在该方法中把需要的参数通过socket的形式发送给Zygote进程执行fork命令
/// ZygoteProcess.java
private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr)
throws ZygoteStartFailedEx, IOException {
try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
final BufferedWriter usapWriter =
new BufferedWriter(
new OutputStreamWriter(usapSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
final DataInputStream usapReader =
new DataInputStream(usapSessionSocket.getInputStream());
usapWriter.write(msgStr);
usapWriter.flush();
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = usapReader.readInt();
// USAPs can't be used to spawn processes that need wrappers.
result.usingWrapper = false;
if (result.pid >= 0) {
return result;
} else {
throw new ZygoteStartFailedEx("USAP specialization failed");
}
}
}
由于Zygote进程创建成功之后会进入ZygoteInit.java,且在入口方法中创建了Socket Server服务,以接受申请进程创建的请求。所以当Socket Server服务收到创建进程的请求后,会通过Native方法fork创建该进程。当进程创建成功后,会根据创建进程时指定的进程入口类android.app.ActivityThread
反射调用并进入main方法。由此便进入了新进程的世界。
下面说App进程与Launcher进程区别?
从点击Launcher的icon开始,启动App(应用进程),Launcher进程会向AMS发送点击icon的启动信息。AMS收到信息后会先后经过ActivityTaskManagerService->ActivityStartController->ActivityStarter。并通知Launcher进程让HomeActivity进入暂停(生命周期) 。当AMS收到Launcher的已暂停消息后,会检查要启动的Activity所在的进程是否已经启动了,如果已经启动了就打开,如果未启动则通过Process.start(android.app.ActivityThread)来启动一个新的App进程。