Activity 启动流程分析(Android10)

概览

Activity 启动流程比较复杂,分析起来很容易陷入复杂的代码中去,所以我这篇分析文章不会深入的分析代码细节,尽量抛开不重要的东西把启动流程按照重点分成几个部分来分析。
下图是 Activity 启动流程的总览。

(上图红色方块是与 WMS 关联的部分,后面会从这里开始介绍 WMS)
后面我们将以 Android 29 为例,按照上图步骤逐步分析。

Intent 解析到 Activity

调用 startActivity 之后,经过几步辗转最终会调用到 AMS 中,而 AMS 又会调用 ActivityStarter 来启动 Activity。
解析 Intent 的任务将由PackageManagerService#resolveIntent方法来处理。
Intent 匹配规则太负责了,我本意是想学习启动流程,所以就没深入进去看代码,就这样吧。

通过 Zygote 创建进程

如果目标进程未启动,则会先启动进程,这里先把启动进程的方法调用栈放上来,方便后面分析。

ActivityStackSupervisor#startSpecificActivityLocked
ActivityManagerService$LocalService#startProcess
ProcessList#startProcessLocked
Process#start
ZygoteProcess#start

方法最终是走到了 ZygoteProcess 中,这个类负责创建进程,我们知道 Android 系统的进程由 Zygote 创建,而 ZygoteProcess 实际上是负责与 Zygote 进行通信的类。

ZygoteProcess#attemptUsapSendArgsAndGetResult方法中打开了一个 LocalSocket 连接,通过这个 Socket 与 Zygote 进行通信。

该 LocalSocket 服务端在 ZygoteServer 中,我们再看下服务端具体是如何做的。

我们主要关注ZygoteServer#runSelectLoop方法,里面最重要的两行代码如下:

ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);

那我们再跳到ZygoteConnection#processOneCommand中看看。

Runnable processOneCommand(ZygoteServer zygoteServer) {
   
    ...
    //处理并应用参数
    args = Zygote.readArgumentList(mSocketReader);
    parsedArgs = new ZygoteArguments(args);
    Zygote.applyUidSecurityPolicy(parsedArgs, peer);
    ...
    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);
    ...
    if (pid == 0) {
   
        return handleChildProc(parsedArgs, descriptors, childPipeFd,
                parsedArgs.mStartChildZygote);
    } else {
   
        handleParentProc(pid, descriptors, serverPipeFd);
        return null;
    }
}

看到没,找了半天,终于找到了 Zygote,这里主要通过Zygote.forkAndSpecialize方法来孵化进程,并获取 pid。

forkAndSpecialize 方法主要就是调用了Zygote.nativeForkAndSpecialize方法,根据名字可以看出来这是一个原生方法,我们就到此为止吧,不继续了。

我们再回到ZygoteConnection#processOneCommand方法中,进程创建完成后,还会继续调用 handleChildProc 方法,我们顺着这个方法继续看下去。

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
                                 FileDescriptor pipeFd, boolean
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值