
在前面SystemUI启动流程中说到,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中,单独抽出了一个ActivityTaskManagerService,主要负责Activity的管理和调度。这里先来看下ActivityManagerService服务的启动:
frameworks/base/services/java/com/android/server/SystemServer.java
1 | private void startBootstrapServices() { |
当SystemServiceManager调用 startService() 时,就会通过反射去创建传进去的class,然后在调用创建对象的 onStart() 方法,这里就是去初始化ActivityTaskManagerService和ActivityManagerService对象,并不会去启动launcher,而且系统服务启动分为三块:
frameworks/base/services/java/com/android/server/SystemServer.java
1 | startBootstrapServices(); // 启动引导服务 |
在startOtherServices()中可以看到:
frameworks/base/services/java/com/android/server/SystemServer.java
1 | private void startOtherServices() { |
这就说明在所有服务初始化完成后,在这里会通知ActivityManagerService的systemReady()启动 launcher 的进程。
下面一起来看 launcher 是如何被启动起来的:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
1 | public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { |
mAtmInternal类型是ActivityTaskManagerInternal,这是一个抽象类,其实现是ActivityTaskManagerService的内部类LocalService:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
1 | final class LocalService extends ActivityTaskManagerInternal { |
这里的mRootActivityContainer类型是RootActivityContainer,按照文档上的说明,这是一个临时类,主要是将ActivityStackSupervisor.java中的一部分逻辑分离出来,在android11中,这个类就已经找不到了。替换成了RootWindowContainer,这里我们跟进 mRootActivityContainer.startHomeOnAllDisplays() 方法看,最终会调用到:startHomeOnDisplay() :
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
1 | boolean startHomeOnDisplay(int userId,String reason,int displayId,boolean allowInstrumenting,boolean fromHomeKey){ |
这里可以分为两步看:
1、通过ActivityTaskManagerService的getHomeIntent()获取到需要启动的intent,在通过resolveHomeActivity()解析出需要启动Activity的信息,
2、mService.getActivityStartController()获取到的是ActivityStartController,这个类的主要作用是用于控制委派启动的Activity。
先来看下ActivityTaskManagerService的getHomeIntent() :
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
1 | Intent getHomeIntent() { |
注意看 intent.addCategory(Intent.CATEGORY_HOME) ,这个代表的就是要启动Activity的意图,通常来说,整个系统的只会有一个应用会在清单文件中配置CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪个作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用启动。(这个 CATEGORY_HOME 配置,说白了就只有 launcher 程序才会有)。
回到主线,接着看mService.getActivityStartController().startHomeActivity() :
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
1 | void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, |
这里主要是先获取一个ActivityStarter(主要用于启动Activity),然后把需要的参数设置进去,最后再调用它的ActivityStarter.execute()方法:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1 | int execute() { |
通过上面代码我们知道,启动是在 executeRequest() 方法里:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1 | private int executeRequest(Request request) { |
ActivityStarter.startActivityUnchecked()
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1 | private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, |
ActivityStarter.startActivityInner()
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
1 | int startActivityInner() { |
RootWindowContainer.resumeFocusedStacksTopActivities()
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
1 | boolean resumeFocusedStacksTopActivities( |
ActivityStack.resumeTopActivityUncheckedLocked()
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
1 | boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { |
ActivityStackSupervisor.startSpecificActivity()
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
1 | void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { |
startSpecificActivity() 这个方法是关键方法,如果进程已经存在直接执行 realStartActivityLocked 去启动 Activity,进程不存在则通过AMS去创建 Socket,然后通知 Zygote 去 fork 进程。由于这里第一次创建,所以会走到 startProcessAsync() 。
Launcher启动流程调用栈:
创建Socket建立连接
ActivityTaskManagerService.startProcessAsync()
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
1 | void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop, |
通过handler发消息执行ActivityManagerInternal.startProcess() ,内部又转调用ActivityManagerService.startProcessLocked() :
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
1 |
|
mProcessList类型是ProcessList,这是一个进程管理类,描述了进程的adj值,当系统资源吃紧时,就会根据这里描述的adj去判断杀死哪个应用来释放资源,可以通过adb shell dumpsys meminfo来查看当前所有进程的分类情况,接着来看下ProcessList.startProcessLocked():
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
1 | final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, |
这里有几个我们需要关注的点,一个是第二个方法定义的entryPoint=”android.app.ActivityThread”,这个就是后面创建进程时会通过反射调用到的类,再来看最后一个方法,这里会执行else if语句,也就是执行ZygoteProcess的start()方法。最终到 ZygoteProcess 的attemptUsapSendArgsAndGetResult 通过 Socket 通信,fork 一个新的 Launcher 进程,调用过程如图:
ZygoteProcess.attemptZygoteSendArgsAndGetResult()
frameworks/base/core/java/android/os/ZygoteProcess.java
1 | private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult( |
Zygote进程处理
ZygoteInit.main
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
1 | public static void main(String argv[]) { |
ZygoteServer.runSelectLoop
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
1 | Runnable runSelectLoop(String abiList) { |
ZygoteConnection.processOneCommand
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
1 | Runnable processOneCommand(ZygoteServer zygoteServer) { |
ZygoteConnection.handleChildProc
这里主要执行到 ZygoteInit.zygoteInit,zygoteInit 进行一些环境的初始化、启动Binder进程等操作,最终反射执行 ActivityThread.main
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
1 | private Runnable handleChildProc(ZygoteArguments parsedArgs, |
Zygote进程调用栈:
ActivityThread中处理
Zygote fork出了 Launcher 的进程,并把接下来的 Launcher 启动任务交给了 ActivityThread 来进行,接下来我们就从 ActivityThread.main方法来分析 Launcher 的创建过程。
frameworks/base/core/java/android/app/ActivityThread.java
1 | public static void main(String[] args) { |
这里就是android层面划分为一个应用进程的开始,初始化一个looper,也就是android中说的主线程,并开始looper循环,这里调用到了ActivitThread.attach() :
frameworks/base/core/java/android/app/ActivityThread.java
1 | private void attach(boolean system, long startSeq) { |
这里会执行if语句里面的内容,mAppThread的类型是ApplicationThread,这个类的主要作用是在ActivityManagerService中回调回ActivityThread中来,mgr是ActivityManagerService的代理,在执行它的ActivityManagerService.attachApplication() 方法:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
1 | public final void attachApplication(IApplicationThread thread, long startSeq) { |
ActivityManagerService.attachApplicationLocked()
调用AMS的 attachApplication(),最终层层调用到 ActivityStackSupervisor 的 realStartActivityLocked,真正准备去启动Activity。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
1 | private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) { |
这里通过AMS最终会调用到ActivityStackSupervisor.realStartActivityLocked():
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
1 | boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, |
ActivityThread调用栈:
小结
至此已经走到 realStartActivityLocked,接下来就是 Activity 的启动流程,Activity 启动下篇文章会单独分析。总结一下 Launcher 启动流程,Launcher的启动经过了三个阶段:
1、SystemServer 创建AMS和ATMS,通过 SystemReady 进入 LauncherActivity 的调用
2、Zygote 进程 fork 出 Launcher 进程,通过 Socket 进行通信
3、进入 ActivityThread 的处理,完成 Launcher 的 Acitivty 启动
本文链接:
http://longzhiye.top/2023/11/25/2023-11-25/