安卓冷启动流程(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);
相关推荐
2501_937860942 小时前
MySQL表的操作:创建、查看、修改、删除完整实战
android·数据库·mysql
我就是妖怪11 小时前
KMP全栈开发:从Android到AI Agent的技术演进与实践
android·人工智能
心平气和量大福大12 小时前
android-实例-蒲公英-更新与安装-5-签名与生成APK
android·java·开发语言
阿pin14 小时前
Android随笔-Serializable与Parcelable
android·serializable·parcelable
天空之城--14 小时前
Android 事件分发机制深度解析——原理、源码与实战综合总结
android
阿pin15 小时前
Android随笔-AIDL
android·开发语言·aidl
2501_9160074716 小时前
Bundle ID 注册与管理 App ID 创建指南 命名规则 权限开关与删除注意事项
android·ios·小程序·https·uni-app·iphone·webview
雨白16 小时前
面向对象六大基本原则实战:从零重构支持引擎切换的网络框架
android·架构
张赐荣17 小时前
Android TalkBack 无障碍优化: 为控件自定义转子导航动作
android·microsoft
天空之城--19 小时前
Android Flutter行业动态与学习参考(2026年8月)
android·flutter