安卓冷启动流程(Android 15)

大纲

Android触控事件处理机制

Zygote进程启动和应用进程创建流程

Handler消息机制

AMS的Activity组件管理

应用Application和Activity组件创建与初始化

应用UI布局与绘制

RenderThread渲染

SurfaceFlinger合成显示

桌面点击图标

Android 系统是由事件驱动的,而 input 是最常见的事件之一,用户的点击、滑动、长按等操作,都属于 input 事件驱动,其中的核心就是 InputReader 和 InputDispatcher。InputReader 和 InputDispatcher 是跑在 SystemServer进程中的两个 native 循环线程,负责读取和分发 Input 事件。整个处理过程大致流程如下:

1)InputReader负责从EventHub里面把Input事件读取出来,然后交给 InputDispatcher 进行事件分发;

2)InputDispatcher在拿到 InputReader获取的事件之后,对事件进行包装后,寻找并分发到目标窗口;

3)InboundQueue队列("iq")中放着InputDispatcher从InputReader中拿到的input事件;

4)OutboundQueue("oq")队列里面放的是即将要被派发给各个目标窗口App的事件;

5)WaitQueue队列里面记录的是已经派发给 App("wq"),但是 App还在处理没有返回处理成功的事件;

6)PendingInputEventQueue队列("aq")中记录的是应用需要处理的Input事件,这里可以看到input事件已经传递到了应用进程;

7)deliverInputEvent 标识 App UI Thread 被 Input 事件唤醒;

8)InputResponse 标识 Input 事件区域,这里可以看到一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件的处理阶段都被算到了这里;

9)App 响应处理Input 事件,内部会在其界面View树中传递处理。

从桌面点击应用图标启动应用,system_server的native线程InputReader首先负责从EventHub中利用linux的epolle机制监听并从屏幕驱动读取上报的触控事件,然后唤醒另外一条native线程InputDispatcher负责进行进一步事件分发。

InputDispatcher中会先将事件放到InboundQueue也就是"iq"队列中,然后寻找具体处理input事件的目标应用窗口,并将事件放入对应的目标窗口OutboundQueue也就是"oq"队列中等待通过SocketPair双工信道发送到应用目标窗口中。

桌面应用界面View中在连续处理一个ACTION_DOWN的TouchEvent触控事件和多个ACTION_MOVE,直到最后出现一个ACTION_UP的TouchEvent事件后,判断属于onClick点击事件,然后透过ActivityManager Binder调用AMS的startActivity服务接口触发启动应用的逻辑。

桌面启动应用

Launcher.java -> super.startActivitySafely()

Launcher启动后会将已安装应用程序的快捷图标显示到界面上,当我们点击应用程序的快捷图标时就会调用Launcher的startActivitySafely方法,如下所示。

正常会走super.startActivitySafely(v, intent, item);

java 复制代码
public class Launcher extends StatefulActivity<LauncherState>
public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
        extends BaseDraggingActivity 
public abstract class BaseDraggingActivity extends BaseActivity
public abstract class BaseActivity extends Activity implements ActivityContext 

从调用关系可以看出,会调到ActivityContext.java的startActivitySafely

ActivityContext.java -> startActivitySafely()

java 复制代码
        try {
            ......
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                // 调用startActivity
                context.startActivity(intent, optsBundle);
相关推荐
饭小猿人1 小时前
Android 腾讯X5WebView如何禁止系统自带剪切板和自定义剪切板视图
android·java
_李小白1 小时前
【android opencv学习笔记】Day 8: remap(像素位置重映射)
android·opencv·学习
美狐美颜SDK开放平台1 小时前
多场景美颜SDK解决方案:直播APP(iOS/安卓)开发接入详解
android·人工智能·ios·音视频·美颜sdk·第三方美颜sdk·短视频美颜sdk
嗷o嗷o2 小时前
Android BLE 里,MTU、分包和长数据发送到底该怎么处理
android
Gary Studio3 小时前
Android AIDL HAL工程结构示例
android
y = xⁿ4 小时前
MySQL八股知识合集
android·mysql·adb
andr_gale5 小时前
04_rc文件语法规则
android·framework·aosp
祖国的好青年6 小时前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js
黄林晴6 小时前
警惕!AGP 9.2 别只改版本号,R8 规则与构建链路全线收紧
android·gradle