• Android 11 Launcher启动流程


    Launcher 进程即 Android 系统桌面也是一个应用程序。随着 Android 系统不断更新,Launcher 也已经升级到现在的 Launcher3 了,本文主要研究 Launcher3 的启动过程。Launcher 作为一个应用程序由AMS(ActivityManagerService)来管理进程调度与启动,AMS是 Android 中最核心的系统服务,几乎所有的应用都需要与AMS通信。本文先从AMS启动入手,再分析由AMS启动 Launcher 的这个过程。

    AMS的启动过程
    从上篇文章安卓系统启动流程得知AMS是由 SystemServer 启动的,下面看看 SystemServer 内部执行流程

    1.创建系统上下文

    1.     private void createSystemContext() {
    2.         ActivityThread activityThread = ActivityThread.systemMain();
    3.         mSystemContext = activityThread.getSystemContext();
    4.         mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    5.  
    6.         final Context systemUiContext = activityThread.getSystemUiContext();
    7.         systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    8.     }


    2.创建系统服务

    // Create the system service manager.

    1. mSystemServiceManager = new SystemServiceManager(mSystemContext);
    2. mSystemServiceManager.setStartInfo(mRuntimeRestart,
    3.         mRuntimeStartElapsedTime, mRuntimeStartUptime);
    4. LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    5. 3.startBootstrapServices()

    引导服务中启动了ATMS(ActivityTaskManagerServici)、AMS等服务,其中ATMS是 Android 10中新增的,本来都是AMS来管理,可能考虑到AMS职责太多代码太庞大,所以单独拆出来ATMS用于管理Activity。

    //创建ATMS和AMS

    1. ActivityTaskManagerService atm = mSystemServiceManager.startService(
    2.         ActivityTaskManagerService.Lifecycle.class).getService();
    3. mActivityManagerService = ActivityManagerService.Lifecycle.startService(
    4.         mSystemServiceManager, atm);


    ATMS和AMS内部都有一个 Lifecycle 用来创建并启动,publishBinderService 最后会调用到        ServiceManager.addService(),注册 Binder 服务。

    //ActivityTaskManagerService内部类

    1. public static final class Lifecycle extends SystemService {
    2.    private final ActivityTaskManagerService mService;
    3.  
    4.    public Lifecycle(Context context) {
    5.         super(context);
    6.         mService = new ActivityTaskManagerService(context);
    7.    }
    8.  
    9.    @Override
    10.    public void onStart() {
    11.        publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
    12.        mService.start();
    13.    }
    14. }


    4.startCoreServices 和 startOtherServices

    startCoreServices 启动核心服务,基本都是系统的服务,startOtherServices启动其他服务,WMS就在这里启动。systemReady 方法会启动 Launcher 进程。

    // 启动Launcher

    1. mActivityManagerService.systemReady(() -> {
    2.             mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
    3.     startSystemUi(context, windowManagerF);
    4.          
    5. }


     SystemServer执行流程图:

    Launcher启动流程
    上文说到AMS的 systemReady 方法会启动 Launcher,来看看 Launcher 是如何被启动起来的。

    ActivityManagerService.java

    1. public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
    2.      ...
    3.      mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    4.      ...
    5. }


    systemReady 中会调用 mAtmInternal.startHomeOnAllDisplays 方法,mAtmInternal 就是ActivityTaskManagerInternal,在ATMS的构造方法中初始化,是由ATMS对外提供的一个抽象类,真正的实现是在ATMS中的 LocalService,所以执行到了 LocalService 的 startHomeOnAllDisplays方法。

    //ActivityTaskManagerService.java # LocalService
     

    1. public boolean startHomeOnAllDisplays(int userId, String reason) {
    2.     synchronized (mGlobalLock) {
    3.         return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
    4.     }
    5. }


    然后会调用到 startHomeOnTaskDisplayArea 方法,这里 getHomeIntent 方法中创建了一个 category为 CATEGORY_HOME 的 Intent,这个 category 会在 Launcher3 的 AndroidManifest.xml 中配置,表明是 HomeActivity,最后再调用 startHomeActivity 方法。

     

    1.   boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
    2.             boolean allowInstrumenting, boolean fromHomeKey) {
    3.         Intent homeIntent = null;
    4.         ActivityInfo aInfo = null;
    5.  
    6.         homeIntent = mService.getHomeIntent();
    7.         aInfo = resolveHomeActivity(userId, homeIntent);
    8.  
    9.         mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
    10.                 taskDisplayArea);
    11.         return true;
    12.     }


    ActivityStartController.startHomeActivity

    obtainStarter 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动。这里多个 set 方法设置启动需要的参数, 最后 execute 方法才是真正的启动逻辑。这段代码看起来像构建者模式,实际上是工厂 + 享元 + 链式调用。

    //ActivityStartController.java
     

    1. void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
    2.             TaskDisplayArea taskDisplayArea) {
    3.         //obtainStarter 返回一个 ActivityStarter,它负责 Activity 的启动
    4.         mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
    5.                 .setOutActivity(tmpOutRecord)
    6.                 .setCallingUid(0)
    7.                 .setActivityInfo(aInfo)
    8.                 .setActivityOptions(options.toBundle())
    9.                 .execute();
    10.     }


    ActivityStarter.extcute 

    onExecutionComplete 方法在 ActivityStartController 清除数据放回startPool池子中。

    1.     int execute() {
    2.         try {
    3.             int res;
    4.             synchronized (mService.mGlobalLock) {
    5.                 ...
    6.                 //执行这个方法
    7.                 res = executeRequest(mRequest);
    8.                 ...
    9.         } finally {
    10.             onExecutionComplete();
    11.         }
    12.     }


     ActivityStarter.executeRequest 

    1.     private int executeRequest(Request request) {
    2.         //调用 startActivityUnchecked
    3.         mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
    4.                 request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
    5.                 restrictedBgActivity, intentGrants);
    6.         return mLastStartActivityResult;
    7.     }


     ActivityStarter.startActivityUnchecked

    1.     private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
    2.                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    3.                 int startFlags, boolean doResume, ActivityOptions options, Task inTask,
    4.                 boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    5.         int result = START_CANCELED;
    6.         try {
    7.             //延时布局
    8.             mService.deferWindowLayout();
    9.             //执行startActivityInner
    10.             result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
    11.                     startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
    12.         } finally {
    13.             //恢复布局
    14.             mService.continueWindowLayout();
    15.         }
    16.         return result;
    17.     }


     ActivityStarter.startActivityInner

    1. int startActivityInner()
    2.        if (mDoResume) {
    3.             //ActivityRecord 记录着 Activity 信息
    4.             final ActivityRecord topTaskActivity =
    5.                     mStartActivity.getTask().topRunningActivityLocked();
    6.             if (!mTargetStack.isTopActivityFocusable()
    7.                     || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
    8.                     && mStartActivity != topTaskActivity)) {
    9.                 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
    10.             } else {
    11.                 //执行resumeFocusedStacksTopActivities
    12.                 mRootWindowContainer.resumeFocusedStacksTopActivities(
    13.                         mTargetStack, mStartActivity, mOptions);
    14.             }
    15.         }
    16.         return START_SUCCESS;
    17.     }


    RootWindowContainer.resumeFocusedStacksTopActivities 

    1. boolean resumeFocusedStacksTopActivities(
    2.             ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    3.         //如果是栈顶Activity,启动resumeTopActivityUncheckedLocked
    4.         if (targetStack != null && (targetStack.isTopStackInDisplayArea()
    5.                 || getTopDisplayFocusedStack() == targetStack)) {
    6.             result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    7.         }
    8.         if (!resumedOnDisplay) {
    9.             //获取栈顶的 ActivityRecord
    10.             final ActivityStack focusedStack = display.getFocusedStack();
    11.             if (focusedStack != null) {
    12.                 //执行resumeTopActivityUncheckedLocked
    13.                 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    14.             }
    15.         }
    16.       return result;
    17. }

    ActivityStack.resumeTopActivityUncheckedLocked

       

    1. boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    2.         boolean result = false;
    3.         try {
    4.             mInResumeTopActivity = true;
    5.             //执行resumeTopActivityInnerLocked,
    6.             //最终调用到ActivityStackSupervisor.startSpecificActivity
    7.             result = resumeTopActivityInnerLocked(prev, options);
    8.         } finally {
    9.             mInResumeTopActivity = false;
    10.         }
    11.         return result;
    12.     }


    ActivityStackSupervisor.startSpecificActivity

    这个方法是关键方法,如果进程已经存在直接执行 realStartActivityLocked 去启动 Activity,进程不存在则通过AMS去创建 Socket,然后通知 Zygote 去 fork 进程。由于这里第一次创建,所以走到 startProcessAsync

    1.     void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    2.         // Is this activity's application already running?
    3.         final WindowProcessController wpc =
    4.                 mService.getProcessController(r.processName, r.info.applicationInfo.uid);
    5.  
    6.         boolean knownToBeDead = false;
    7.         //进程存在
    8.         if (wpc != null && wpc.hasThread()) {
    9.             try {
    10.                 //真正启动Activity方法
    11.                 realStartActivityLocked(r, wpc, andResume, checkConfig);
    12.                 return;
    13.             } catch (RemoteException e) {
    14.                 Slog.w(TAG, "Exception when starting activity "
    15.                         + r.intent.getComponent().flattenToShortString(), e);
    16.             }
    17.             // If a dead object exception was thrown -- fall through to
    18.             // restart the application.
    19.             knownToBeDead = true;
    20.         }
    21.  
    22.         r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
    23.  
    24.         final boolean isTop = andResume && r.isTopRunningActivity();
    25.         //进程不存在 mService =ATMS
    26.         mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    27.     }

    以上流程调用栈如图

    创建Socket建立连接
    ActivityTaskManagerService.startProcessAsync

    1. void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
    2.             String hostingType) {
    3.      //执行startProcess
    4.      final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
    5.                     mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
    6.                     isTop, hostingType, activity.intent.getComponent());
    7.      mH.sendMessage(m);
    8.        
    9.     }


    调用 startProcessLocked,然后到 Process 的 start,最终到 ZygoteProcess 的attemptUsapSendArgsAndGetResult 通过 Socket 通信,fork 一个新的 Launcher 进程,调用过程如图

     ZygoteProcess.attemptZygoteSendArgsAndGetResult

    通过 Socket 连接 Zygote 进程,把应用进程的一些参数写给前面连接的 zygote 进程

     

    1.   private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
    2.             ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    3.         try {
    4.             final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
    5.             final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
    6.  
    7.             zygoteWriter.write(msgStr);把应用进程的一些参数写给前面连接的zygote进程
    8.             zygoteWriter.flush();//进入Zygote进程,处于阻塞状态
    9.             //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
    10.             Process.ProcessStartResult result = new Process.ProcessStartResult();
    11.             result.pid = zygoteInputStream.readInt();
    12.             result.usingWrapper = zygoteInputStream.readBoolean();
    13.             return result;
    14.         } catch (IOException ex) {
    15.             zygoteState.close();
    16.         }
    17.     }

    Zygote进程处理
    ZygoteInit.main

    1. public static void main(String argv[]) {
    2.     Runnable caller;
    3.     if (startSystemServer) {
    4.         //Zygote Fork出的第一个进程 SystmeServer
    5.         Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
    6.  
    7.         if (r != null) {
    8.             r.run();
    9.             return;
    10.         }
    11.     }
    12.     //循环等待fork出其他的应用进程,比如Launcher
    13.     caller = zygoteServer.runSelectLoop(abiList);
    14.     ...
    15.     if (caller != null) {
    16.         caller.run(); //执行runSelectLoop返回的Runnable对象,进入子进程
    17.     }
    18. }


    ZygoteServer.runSelectLoop 

    1. Runnable runSelectLoop(String abiList) {
    2.     while (true) {
    3.         int pollReturnValue;
    4.             try {
    5.                 //epoll机制 循环
    6.                 pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
    7.             } catch (ErrnoException ex) {
    8.                 throw new RuntimeException("poll failed", ex);
    9.             }
    10.             ...
    11.             //来了消息后,调用processOneCommand()来进行进程的处理
    12.             final Runnable command =  connection.processOneCommand(this);
    13.     } 
    14. }


    ZygoteConnection.processOneCommand 

    1. Runnable processOneCommand(ZygoteServer zygoteServer) {
    2.             //fork进程,得到新进程pid
    3.             //pid=0 表示Zygote  fork子进程成功
    4.             //pid > 0 表示子进程 的真正的PID
    5.             pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
    6.                 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
    7.                 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
    8.                 parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
    9.                 parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
    10.                 parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
    11.         try {
    12.             //fork成功,第一次返回的pid = 0
    13.             if (pid == 0) {
    14.                 return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
    15.             } else {
    16.                 handleParentProc(pid, serverPipeFd);
    17.                 return null;
    18.             }
    19. }

     ZygoteConnection.handleChildProc

    这里主要执行到 ZygoteInit.zygoteInit,zygoteInit 进行一些环境的初始化、启动Binder进程等操作,最终反射执行 ActivityThread.main

    1.     private Runnable handleChildProc(ZygoteArguments parsedArgs,
    2.             FileDescriptor pipeFd, boolean isZygote) {
    3.         closeSocket();
    4.         Zygote.setAppProcessName(parsedArgs, TAG);
    5.             if (!isZygote) {
    6.                 //App进程将会调用到这里,最终反射执行ActivityThread.main
    7.                 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
    8.                         parsedArgs.mDisabledCompatChanges,
    9.                         parsedArgs.mRemainingArgs, null /* classLoader */);
    10.             } else {
    11.                 return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
    12.                         parsedArgs.mRemainingArgs, null /* classLoader */);
    13.             }
    14.         
    15.     }


    Zygote进程调用栈如图 
    ActivityThread中处理 
    Zygote fork出了 Launcher 的进程,并把接下来的 Launcher 启动任务交给了 ActivityThread 来进行,接下来我们就从 ActivityThread.main方法来分析 Launcher 的创建过程。

    ActivityThread.main

    创建 ActivityThread 对象,调用 attach 进行处理,最终进入 Looper 循环

    1.     public static void main(String[] args) {
    2.         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    3.         //创建主线程Looper
    4.         Looper.prepareMainLooper();
    5.         ActivityThread thread = new ActivityThread();
    6.         //执行attach
    7.         thread.attach(false, startSeq);
    8.         //开启循环
    9.         Looper.loop();
    10.         throw new RuntimeException("Main thread loop unexpectedly exited");
    11.     }


     ActivityThread.attach

    1. private void attach(boolean system, long startSeq) {
    2.    
    3.    RuntimeInit.setApplicationObject(mAppThread.asBinder());
    4.    final IActivityManager mgr = ActivityManager.getService();
    5.    try {
    6.        //应用的句柄发给AMS,从而使AMS可以管理新进程
    7.        mgr.attachApplication(mAppThread, startSeq);
    8.    } catch (RemoteException ex) {
    9.        throw ex.rethrowFromSystemServer();
    10.    }
    11.  
    12. }


     ActivityManagerService.attachApplication

    1.     public final void attachApplication(IApplicationThread thread, long startSeq) {
    2.         if (thread == null) {
    3.             throw new SecurityException("Invalid application interface");
    4.         }
    5.         synchronized (this) {
    6.             //通过Binder获取传入的pid信息
    7.             int callingPid = Binder.getCallingPid();
    8.             final int callingUid = Binder.getCallingUid();
    9.             final long origId = Binder.clearCallingIdentity();
    10.             //执行attachApplicationLocked
    11.             attachApplicationLocked(thread, callingPid, callingUid, startSeq);
    12.             Binder.restoreCallingIdentity(origId);
    13.         }
    14.     }


    ActivityManagerService.attachApplicationLocked

    调用ATM的 attachApplication(),最终层层调用到 ActivityStackSupervisor 的 realStartActivityLocked,真正准备去启动Activity。

    1. private final boolean attachApplicationLocked(IApplicationThread thread,
    2.         int pid, int callingUid, long startSeq) {
    3.     //如果当前的Application记录仍然依附到之前的进程中,则清理掉
    4.     if (app.thread != null) {
    5.         handleAppDiedLocked(app, true, true);
    6.     }
    7.     if (normalMode) {
    8.       //调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
    9.       didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
    10.     }
    11.     return true;
    12. }


     ActivityThread调用栈如图 

     

  • 相关阅读:
    react hook
    [附源码]Java计算机毕业设计SSM仿咸鱼二手物品交易系统
    java 企业工程管理系统软件源码 自主研发 工程行业适用
    Andorid11 暗码启动应用(一)
    Docker运维,基础
    在R语言中进行缺失值填充:估算缺失值
    解决cmd命令行输入mysql提示不是内部或外部命令的错误
    基于 Appium 的 Android UI 自动化测试!
    如果你要去拜访国外客户需要做哪些准备
    promise加强
  • 原文地址:https://blog.csdn.net/a546036242/article/details/126409880