安卓冷启动流程(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);
相关推荐
冬奇Lab12 小时前
PMS核心机制:应用安装与包管理深度解析
android·源码阅读
城东米粉儿14 小时前
Android 计算滑动帧率 笔记
android
城东米粉儿16 小时前
Android Choreographer 和 looper 结合使用 监控
android
城东米粉儿16 小时前
Android inline Hook 笔记
android
城东米粉儿16 小时前
Android 防止 Printer 覆盖笔记
android
Android系统攻城狮20 小时前
Android tinyalsa深度解析之pcm_get_timestamp调用流程与实战(一百一十八)
android·pcm·tinyalsa·android hal·audio hal
yuezhilangniao1 天前
win10环境变量完全指南:Java、Maven、Android、Flutter -含我的环境备份
android·java·maven
奔跑吧 android1 天前
【车载Audio】【AudioHal 06】【高通音频架构】【深入浅出 Android Audio HAL:从加载到函数指针绑定的全链路解析】
android·音视频·audioflinger·aosp13·8295·audiohal·高通音频架构
无巧不成书02181 天前
Kotlin Multiplatform (KMP) 鸿蒙开发整合实战|2026最新方案
android·开发语言·kotlin·harmonyos·kmp