SP与ANR

文章探讨了在Android应用中,从传统的SharedPreferences到新推出的DataStore的迁移过程,强调了DataStore在性能和安全方面的优势。它提供了更好的数据持久化解决方案,适合开发者寻求更高效、可靠的存储选项。
<think>我们之前已经讨论过输入事件分发流程和ANR检测机制,现在用户再次询问,需要更详细地说明。 输入事件分发流程:从硬件驱动到应用层View的传递过程,以及ANR检测机制(特别是InputDispatcher的超时监控)。 注意:必须按照规则,在回答后提出3-5个相关问题,以“§§相关问题§§”开头,然后列出问题,禁止换行分散。 回答结构: 1. 详细解释输入事件分发流程(包括Native层和Java层)。 2. 重点说明ANR检测机制(InputDispatcher如何监控超时)。 3. 最后提出相关问题。 注意:使用中文,代码示例可以用伪代码或关键代码片段。</think>在Android系统中,**输入事件分发流程ANR检测机制**紧密关联,以下是详细解析: --- ### **一、输入事件分发全流程** ```mermaid graph TD A[硬件驱动] --> B(InputReader) B -->|原始事件| C[InputDispatcher] C -->|跨进程分发| D[ViewRootImpl] D -->|事件传递链| E[Activity] E --> F[DecorView] F --> G[ViewGroup] G --> H[具体View] ``` 1. **InputReader**(Native层) - 从`/dev/input`读取原始输入数据 - 转换为标准事件对象(`KeyEvent`/`MotionEvent`) 2. **InputDispatcher**(核心分发器) - 通过`WindowManagerService`获取焦点窗口 - 通过Binder IPC将事件发送到应用进程: ```c++ // 伪代码:事件分发 status_t InputDispatcher::dispatchEvent() { sp<Connection> connection = findFocusWindowConnection(); connection->inputPublisher.publishMotionEvent(event); // Binder调用 } ``` 3. **应用层事件传递** ```java // ViewRootImpl.java final class WindowInputEventReceiver extends InputEventReceiver { @Override public void onInputEvent(InputEvent event) { enqueueInputEvent(event); // 传递到主线程消息队列 } } ``` - 事件经`Activity.dispatchTouchEvent()` → `ViewGroup` → 最终`View` --- ### **二、ANR检测机制** #### **触发条件** 当主线程**5秒内**未完成事件处理时触发ANR,检测逻辑集中在InputDispatcher: 1. **时间戳记录** InputDispatcher为每个事件标记两个关键时间: - `dispatchTime`:事件分发时刻 - `responseTime`:要求应用完成处理的截止时间(= dispatchTime + 5s) 2. **超时监控线程** ```c++ // InputDispatcher.cpp void InputDispatcher::dispatchOnce() { if (!mPendingEvent) { mPendingEvent = mInboundQueue.dequeue(); mPendingEvent->dispatchTime = now(); // 记录分发时间 } startAnrCheck(mPendingEvent); // 启动监控 } ``` 3. **超时判定** ```c++ // 监控线程伪代码 while (event = getUnfinishedEvent()) { if (currentTime > event->responseTime) { triggerAnr(targetApp); // 触发ANR } } ``` #### **ANR日志生成** 1. 调用`appNotResponding()`收集主线程堆栈 2. 写入`/data/anr/traces.txt` 3. 弹出ANR对话框(应用未响应) --- ### **三、关键优化点** 1. **避免主线程阻塞** ```kotlin override fun onTouchEvent(event: MotionEvent): Boolean { when (event.action) { ACTION_DOWN -> CoroutineScope(Dispatchers.IO).launch { heavyTask() // 耗时操作移出主线程 } } return true } ``` 2. **缩短事件传递链** - 减少ViewGroup嵌套层级 - 使用`ViewStub`延迟加载复杂布局 3. **监控工具** ```bash adb shell dumpsys input # 查看事件分发状态 adb shell am monitor # 实时监控ANR ``` --- ### **四、典型ANR场景** | 场景 | 原因 | 解决方案 | |---------------------|-----------------------|-----------------------| | 主线程数据库操作 | SQLite阻塞主线程 | 用Room+协程异步处理 | | 复杂布局绘制 | View.onDraw()耗时过长 | 简化布局/使用SurfaceView | | 跨进程同步调用 | Binder调用阻塞 | 改为异步通信 | | 事件分发逻辑死循环 | onTouchEvent()未返回 | 检查事件处理返回值逻辑 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值