[笔记] 应用启动过程梳理

冷启动过程

一、概述
1、整个过程包括如下几步:
(1)应用程序启动
(2)首帧的绘制与渲染
(3)首帧的合成与送显
在这里插入图片描述
从 Systrace 中,可以看到 Frames 这一行,每一帧主要分为:红色、黄色、绿色的 “圆饼”:
<1> 红色:定义为 terrible frame,代表从 performTraversal 到 renderThread 绘制完成的总时间超过了 2 * VSync(详见:VSync信号处理);
<2> 黄色:定义为 bad frame,代表总时间在1 * VSync ~ 2 * VSync之间(注:在有 renderThread 的情况下,超过 1 * VSync 不一定会导致掉帧);
<3> 绿色:定义为 ok frame,代表总时间在 1 * VSync 以内。

二、详述三个过程
1、应用程序启动(分为两个阶段)
(1)进程创建阶段
在应用冷启动过程中,先确定调用的 Activity 以及对信息与权限的验证,并调整其 task 和 stack 之后,会开始准备创建进程,进程创建流程如下:
(代码路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/core/java/android/os/ZygoteProcess.java
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java)
在这里插入图片描述
Zygote 初始化过程中,先将启动参数封装成 ZygoteState,最后调用 runSelectLoop() 函数,随时待命,当通过 socket 获取到请求信息,runOnce 就开始读取参数列表,并执行 forkAndSpecialize() 函数来创建进程,然后就是创建 Binder 线程池以及通过反射调用 ActivityThread 的 main 函数等。
(代码路径:frameworks/base/core/java/com/android/internal/os/Zygote.java)
在这里插入图片描述
在这里插入图片描述
PostFork 过程就是在 forkAndSpecialize 与 handleChildProc 之间,描述进程 fork 的过程。
ZygoteInit 过程就是描述进程启动之后的一些准备工作的。

(2)Activity启动阶段
上面进程创建好之后,将进入Activity的启动阶段,包括:对要启动的Activity信息权限的验证、数据的封装、任务栈的调整等一系列操作。最后进入应用的 ActivityThread 。
在这里插入图片描述
上图中 ActivityThreadMain 就是反映了 ActivityThread 的 mian() 方法执行过程,这个方法内部就是创建 ActivityThread,并让它的 Looper 循环运行起来:
(代码路径:frameworks/base/core/java/android/app/ActivityThread.java)
在这里插入图片描述
接下来就是 bindApplication 过程,包括:
<1> 加载应用资源、load Class 到内存
<2> 创建上下文 Context
<3> 初始化 Instrumentation,并通过它调用 application 的 onCreate()
在这里插入图片描述
然后就是 scheduleLaunchActivity 过程,包括:
<1> 创建 Activity,加载应用的布局:setContentView(),创建 DecorView,并把 .xml 文件的 View 树解析出来,加到 DecorView 上的 ContentParent 部分
<2> Activity 调用 makeVisible(),通过 WindowManagerGlobal 执行 addView 操作,开始下一个阶段的绘制工作 。
在这里插入图片描述

2、首帧的绘制与渲染
第一阶段的App启动完成后,开始进入第二个 Vsync 信号响应阶段,如下:
在这里插入图片描述
(代码路径:frameworks/base/core/java/android/view/Choreographer.java)
在这里插入图片描述
Choreographers 作为用户层监听 Vsync 信号的处理者,它统一输入、绘制、动画的处理时机,主要做两件事:
<1> 通过 postCallback 请求 vsync 信号
<2> 收到 vsync 信号并回调

一旦接收到回调信号,则通过 doFrame() 方法,统一对这三种事件(输入、绘制、动画)进行回调
(注:doFrame() 方法内主要处理了:input、traversal、animation)
其中,traversal 阶段主要执行视图绘制流程,该视图绘制流程又分为:软件绘制、硬件加速(ViewRootImpl.java)。这些的 draw 过程都是在应用层构建 DisplayList 的数据封装,其中 ViewTree 中的每个 View 对应一个 RenderNode 节点。

与此同时,除了 UI Thread 外,还有一个 Render Thread 被初始化:开始进行 setSurface 的工作,这个工作做了一系列的初始化,最终创建并设置 EGL Context,它最主要的任务就是:dequeueBuffer / queueBuffer 操作。
在这里插入图片描述
接下来就是 DrawFrame 过程:
在这里插入图片描述
硬件加速把视图的渲染工作转到了一个新的线程(RenderThread)中来处理,其中主要包括:
<1> syncFrameState/prepareThree:用于将 UI Thread 的 DisplayList 同步到 Render Thread 来,这个同步过程是阻塞 UI Thread 的,此时的 UI Thread 是 sleep 状态的。
<2> dequeueBuffer:通过 Surface 申请存放绘制数据的 Buffer。
<3> flash commands:DisplayList 按层重新组织数据:LayerBuilder,并转为 OpenGL 命令,缓存在本地的 GL 命令缓冲区中。
<4> eglSwapBuffers:通过 Surface queueBuffer 将绘制好的数据放入之前申请好的 Buffer 中,并通知 SurfaceFlinger 去合成。

3、首帧的合成与送显
第二阶段 RenderThread 完成了渲染,最终通过 queueBuffer 把保存了数据的 Buffer 扔给 SurfaceFlinger,等待合成。 queueBuffer 是一个 binder call,对端是 surfaceFlinger,如下:
在这里插入图片描述
surfaceFlinger 初始化好之后,主线程 run() 方法会执行 MessageQueue.cpp 中的 waitForEvent() 方法,等待接收消息。一旦视图变化,就会发起 invalidate vsync 请求,waitForEvent() 接收到对应的 invalidate 消息进行处理,正常情况下,surfaceFlinger 处理消息间隔时间在 16.67ms 左右,而 queueBuffer 过程本身就会发起 invalidate vsync 请求。
在这里插入图片描述
接收到数据后,会进行如下一些处理:
在这里插入图片描述
其中,onMessageReceived() 中会接受到两种消息:invalidate、refresh
在这里插入图片描述
(1)INVALIDATE 消息
在 Render Thread swapBuffer 过程中,主要做两件事:1.更新 Layer;2.触发 invalidate sf vsync 请求。
SurfaceFlinger::onMessageReceived 接收到 invalidate sf vsync 请求,主要执行两个方法:
<1> handleMessageTransaction()
该方法的核心是:handleTransaction,主要针对 Layer 和 Display 的变化,更新脏区域。
<2> handleMessageInvalidate()
该方法主要调用 handlePageFilp() 函数,其作用主要是从各 Layer 对应的 BufferQueue 中,拿到图形缓冲区的数据,并根据内容更新脏区域,并把 GraphicBuffer 映射为 OpenGL 的 texture。
这两个方法共同决定是否需要发送 refresh sf vsync 请求,即:signalRefresh()。

(2)REFRESH 消息
接收到 refresh 消息后,主要执行 handleMessageRefresh() 方法,进行合并和渲染输出,代码如下:
在这里插入图片描述
完成合成之后,releaseBuffer,释放之前 latchBuffer 获取的 GraphicsBuffer 。

三、应用启动完整过程
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值