当前位置:首页 » 安卓系统 » imsandroid

imsandroid

发布时间: 2023-08-17 11:51:07

❶ Android输入法IMMS服务启动流程(3)(启动IMS应用)

接上一篇,IMMS设置当前默认输入法为LatinIME输入法后,调用onCreate方法,然后会调用startInputInnerLocked启动输入法LatinIME的服务

本章节主要分析,onCreate生命周期中,各个流程调用

bindServiceAsUser启动的服务是LatinIME

如上图流程图,服务启动后,会调用到InputMethodManagerService的方法

该流程的主要逻辑:

完成对mMethodList和mMethodMap的数据初始化;检查当前默认的输入法(LatinIME)服务是否存在,很明显,经过systemrunning过程以后,
mMethodMap已经包含了LatinIME,因此不会重复执行选择和设定另外输入法为默认输入法的操作

该方法主要是检查默认的LatinIME是否是可用的可用的输入法,如果不可用,则设置为可用;
对应的settingprovider字段为:

经过以上流程后,默认输入法依然为LatinIME输入法,该流程的主要作用为,将启动的输入法应用更新到可用列表enabled_input_methods中;
不过,目前默认的输入法依然为LatinIME输入法,跟重启手机前,我们设置的输入法(搜狗输入法)依然不一致

下一篇文章,我们研究下,输入法启动过程中的onBind和onServiceConnected流程

❷ Android View 事件分发机制

Android 事件机制包含系统启动流程、输入管理(InputManager)、系统服务和 UI 的通信(WindowManagerService + ViewRootImpl + Window)、事件分发等一系列的环节。

Android 系统中将输入事件定义为 InputEvent,根据输入事件的类型又分为了 KeyEvent(键盘事件) 和 MotionEvent(屏幕触摸事件)。这些事件统一由系统输入管理器 InputManager 进行分发。

在系统启动的时候,SystemServer 会启动 WindowManagerService,WMS 在启动的时候通过 InputManager 来负责监控键盘消息。

InputManager 负责从硬件接收输入事件,并将事件通过 ViewRootImpl 分发给当前激活的窗口处理,进而分发给 View。

Window 和 InputManagerService 之间通过 InputChannel 来通信,底层通过 socket 进行通信。

Android Touch 事件的基础知识:

KeyEvent 对应了键盘的输入事件;MotionEvent 就是手势事件,鼠标、笔、手指、轨迹球等相关输入设备的事件都属于 MotionEvent。

InputEvent 统一由 InputManager 进行分发,负责与硬件通信并接收输入事件。

system_server 进程启动时会创建 InputManagerService 服务。

system_server 进程启动时同时会启动 WMS,WMS 在启动的时候就会通过 IMS 启动 InputManager 来监控键盘消息。

App 端与服务端建立了双向通信之后,InputManager 就能够将产生的输入事件从底层硬件分发过来,Android 提供了 InputEventReceiver 类,以接收分发这些消息:

Window 和 IMS 之间通过 InputChannel 通信。InputChannel 是一个 pipe,底层通过 socket 进行通信。在 ViewRootImpl.setView() 过程中注册 InputChannel。

Android 事件传递机制是 先分发再处理 ,先由外部的 View 接收,然后依次传递给其内层的 View,再从最内层 View 反向依次向外层传递。

三个方法的关系如下:

分发事件:

应用了树的 深度优先搜索算法 (Depth-First-Search,简称 DFS 算法),每个 ViewGroup 都持有一个 mFirstTouchTarget, 当接收到 ACTION_DOWN 时,通过递归遍历找到 View 树中真正对事件进行消费的 Child,并保存在 mFirstTouchTarget 属性中,依此类推组成一个完整的分发链。在这之后,当接收到同一事件序列的其它事件如 ACTION_MOVE、ACTION_UP 时,则会跳过递归流程,将事件直接分发给下一级的 Child。

ViewGroup 分发事件的主要的任务是找一个 Target,并且用这个 Target 处理事件,主要逻辑如下 :

为什么倒序查找 TouchTarget?
如果按添加顺序遍历,当 View 重叠时(FrameLayout),先添加的 View 总是能消费事件,而后添加的 View 不可能获取到事件。

拦截事件:

[1] Android 事件分发机制的设计与实现
[2] Android 事件拦截机制的设计与实现

❸ Android ANR 机制

广播的 ANR 处理相对简单,主要是再次判断是否超时、记录日志,记录 ANR 次数等。然后就继续调用 processNextBroadcast 函数,处理下一条广播了。

ContentProvider 超时为 CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10s

Activity 的 ANR 是相对最复杂的,也只有 Activity 中出现的 ANR 会弹出 ANR 提示框。
最终的表现形式是:弹出一个对话框,告诉用户当前某个程序无响应,输入一大堆与 ANR 相关的日志,便于开发者解决问题。

InputDispatching:

Activity 最主要的功能之一是交互,为了方便交互,Android 中的 InputDispatcher 会发出操作事件,最终在 InputManagerService 中发出事件,通过 InputChannel,向 Activity 分发事件。交互事件必须得到响应,如果不能及时处理,IMS 就会报出 ANR,交给 AMS 去弹出 ANR 提示框。

KeyDispatching:

如果输入是个 Key 事件,会从 IMS 进入 ActivityRecord.Token.keyDispatchingTimeOut,然后进入 AMS 处理,不同的是,在 ActivityRecord 中,会先截留一次 Key 的不响应,只有当 Key 连续第二次处理超时,才会弹出 ANR 提示框。

窗口焦点:

Activity 总是需要有一个当前窗口来响应事件的,但如果迟迟没有当前窗口(获得焦点),比如在 Activity 切换时,旧 Activity 已经 onPause,新的 Activity 一直没有 onResume,持续超过 5 秒,就会 ANR。
App 的生命周期太慢,或 CPU 资源不足,或 WMS 异常,都可能导致窗口焦点。

1. 判断是否有 focused 组件以及 focused Application:

这种一般是在应用启动时触发,比如启动时间过长在这过程中触发了 keyevent 或者 trackball moteionevent 就会出现。

对应于

2. 判断前面的事件是否及时完成:

对应于

出现这种问题意味着主线程正在执行其他的事件但是比较耗时导致输入事件无法及时处理。

InputDispatcher 超时是最常见的 ANR 类型,而且其类型也比较多。
当用户触摸屏幕或者按键操作,首次触发的是硬件驱动,驱动收到事件后,将该相应事件写入到输入设备节点, 这便产生了最原生态的内核事件。接着,输入系统取出原生态的事件,经过层层封装后成为 KeyEvent 或者 MotionEvent ;最后,交付给相应的目标窗口(Window)来消费该输入事件。可见,输入系统在整个过程起到承上启下的衔接作用。

Input 模块的主要组成:

每一个应用进程都会有一个 SignalCatcher 线程,专门处理 SIGQUIT,来到 art/runtime/signal_catcher.cc :

当应用发生 ANR 之后,系统会收集许多进程,来 mp 堆栈,从而生成 ANR Trace 文件。收集的第一个,也是一定会被收集到的进程,就是发生 ANR 的进程。接着系统开始向这些应用进程发送 SIGQUIT 信号,应用进程收到 SIGQUIT 后开始 mp 堆栈。

[1] developer ANRs
[2] Android ANR 分析详解
[3] 看完这篇 Android ANR 分析,就可以和面试官装逼了!
[4] 微信 Android 团队手把手教你高效监控 ANR
[5] Input 系统—ANR 原理分析 - Gityuan
[6] 彻底理解安卓应用无响应机制 - Gityuan
[7] 理解 Android ANR 的触发原理 - Gityuan

热点内容
滑板鞋脚本视频 发布:2025-02-02 09:48:54 浏览:432
群晖怎么玩安卓模拟器 发布:2025-02-02 09:45:23 浏览:557
三星安卓12彩蛋怎么玩 发布:2025-02-02 09:44:39 浏览:743
电脑显示连接服务器错误 发布:2025-02-02 09:24:10 浏览:537
瑞芯微开发板编译 发布:2025-02-02 09:22:54 浏览:146
linux虚拟机用gcc编译时显示错误 发布:2025-02-02 09:14:01 浏览:237
java驼峰 发布:2025-02-02 09:13:26 浏览:652
魔兽脚本怎么用 发布:2025-02-02 09:10:28 浏览:538
linuxadobe 发布:2025-02-02 09:09:43 浏览:212
sql2000数据库连接 发布:2025-02-02 09:09:43 浏览:726