安卓冷启动流程(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);
相关推荐
郭优秀的笔记2 小时前
html鼠标悬浮提示功能
android·javascript·html
冬奇Lab2 小时前
Android 15存储子系统深度解析(一):Vold与存储管理框架
android·车载系统·系统架构
得一录2 小时前
Android 方向控制控件
android
美狐美颜SDK开放平台3 小时前
跨平台开发实战:直播美颜sdk动态贴纸在 Android / iOS / HarmonyOS 的落地方案
android·ios·harmonyos·美颜sdk·直播美颜sdk·视频美颜sdk·美颜api
2501_916008893 小时前
在不越狱前提下导出 iOS 应用文件的过程,访问应用沙盒目录,获取真实数据
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_915106323 小时前
Android和IOS 移动应用App图标生成与使用 Assets.car生成
android·ios·小程序·https·uni-app·iphone·webview
灵感菇_3 小时前
深入解析 Android事件分发机制
android·ui
TheNextByte13 小时前
如何在Mac上获取Android消息
android·macos
_李小白3 小时前
【Android 美颜相机】第十二天:GPUImageFilterGroup 源码解析
android·数码相机