当前位置: 首页 > java >正文

Input事件处理引起卡顿

一、理论分析

从前面Android卡顿掉帧问题分析之原理篇文章中的分析我们知道,屏幕驱动上报的Input事件要经过框架的InputReader和InputDispatcher线程的读取与分发,然后通过Socket发送到应用进程中,再经过界面View控件树的层层分发后消费处理。这个过程中任意一个流程出现阻塞就能造成用户的触控操作得不到及时的响应,出现用户感知的系统反应延迟或卡顿现象。

二、典型案例分析

问题描述:微博应用界面手势滑动退出时,界面卡住几秒钟才有反应。
问题分析:结合Systrace工具分析问题原因如下:

在这里插入图片描述input_jank.jpg

从以上问题Systrace的分析可以看出,退出应用界面时出现卡住几秒的原因:

首先看Systrace上system_server进程中标识Input事件分发的"iq"和“oq”队列的信息,可以看到框架InputDispatcher对事件的分发处理没有出现阻塞或漏报等异常情况;
从微博应用对应的“wq”队列可以看到,应用进程一直有没有完成处理消费的Input事件,说明问题在微博应用进程侧;
看Systrace上微博应用侧的信息,可以看到应用UI线程很长一段的deliverInputEvent的tag(大概持续2.5秒左右),且“aq:ime”队列中显示有持续很长一段时间的事件处理逻辑。说明应该是在应用进程UI线程中判断Input事件类型为返回键的Key事件,所以先交给输入法应用进行处理,但是输入法进程一直没有完成处理,导致应用UI线程一直处于等待状态无法及时处理此Input事件,说明问题出现在输入法应用侧;
然后我们用ps命令查看当前输入法进程信息,发现输入法进程(pid:5897)当前的状态为“D”,说明处于进程“冻结”的休眠状态,结合Systrace上显示的输入法进程的主线程信息显示,发现其确实是一直处于Sleeping状态。所以此问题出现的原因就是因为输入法进程被异常“冻结”导致的。和负责维护进程“冻结”功能的同事沟通并分析日志后发现,问题的原因是用户安装并设置了新的输入法应用,进程“冻结”模块没有成功识别,将其认定为普通后台进程所以进行了“冻结”从而导致了异常。

到此还剩一个疑问就是为什么输入法进程都被“冻结”而休眠了,应用UI线程在等待2.5秒后还是能继续往下处理Input事件,并成功退出应用Activity界面呢?原因就是应用UI线程进入等待输入法处理Input事件时会设置一个超时,这个时长就是2.5秒,如果超时后输入法进程还是没有处理完,就会强行结束等待的逻辑,由应用UI线程继续往下处理Input事件。相关源码如下所示:

/*frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java*/
...
/**
* Timeout in milliseconds for delivering a key to an IME.
*/
static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500;
...
// Must be called on the main looper
int sendInputEventOnMainLooperLocked(PendingEvent p) {if (mCurChannel != null) {...if (mCurSender.sendInputEvent(seq, event)) {...Message msg = mH.obtainMessage(MSG_TIMEOUT_INPUT_EVENT, seq, 0, p);msg.setAsynchronous(true);mH.sendMessageDelayed(msg, INPUT_METHOD_NOT_RESPONDING_TIMEOUT);//1.处理Input事件时设置一个2500ms的超时检查return DISPATCH_IN_PROGRESS;}...}return DISPATCH_NOT_HANDLED;
}
...
case MSG_TIMEOUT_INPUT_EVENT: {finishedInputEvent(msg.arg1, false, true);// 2.时间到之后如果输入法还是没有完成Input事件处理,则强行结束输入法对事件的处理逻辑return;
}
...

三、优化思路

对用户触控事件的响应速度直接关系到用户对交互设备性能体验的感知,所以一直以来都是系统性能优化工作的重中之重。多年来谷歌,包括SOC厂商都有针对系统Input事件的处理流程作出优化,以提升触控响应速度。例如高通基线上在2018年左右就有一笔提交,优化应用进程侧的Input事件处理流程,大概思路就是识别应用UI线程中收到第一个ACTION_DOWN的Touch事件后,调用sendMessageAtFrontOfQueue接口在应用UI线程的消息队列的最前面插入一帧doFrame绘制任务,这样界面不用等待下一个Vsync的信号的到来就能直接上帧显示,从而减少整个Input触控事件的响应延迟。从Systrace上表现如下图所示:

在这里插入图片描述

国内各大手机厂商也有各自的优化方案。比如硬件上采用触控采样率更高的屏幕,屏幕触控采样率达到240HZ甚至480HZ。再比如监控到触控事件后提升CPU主频,提升触控事件处理相关线程和渲染线程的优先级等方式,从而优化事件触控响应速度。而对于应用APP开发者来说,需要做的就是避免在Input触控事件的分发处理流程中执行耗时操作,以免引起触控延迟或卡顿等性能问题。

整理来自:简书努比亚技术团队

更多framework干货,请关注下面“千里马学框架”

http://www.xdnf.cn/news/14561.html

相关文章:

  • vue3+arcgisAPI4案例:智慧林业资源监测分析平台(附源码下载)
  • 55-Oracle-EXPLAIN PLAN(含23ai )实操
  • 终端里的AI黑魔法:OpenCode深度体验与架构揭秘
  • 启动hardhat 项目,下载依赖的npm问题
  • Taro 跨端应用性能优化全攻略:从原理到实践
  • 【设计模式】6.原型模式
  • FTTR+软路由网络拓扑方案
  • NY339NY341美光固态闪存NW841NW843
  • Flutter ListTile 深度解析
  • 西门子S7通信协议抓包分析应用
  • OSI网络通信模型详解
  • react扩展
  • 智能群跃小助手发布说明
  • 局域网文件共享及检索系统
  • 初学python的我开始Leetcode题10-2
  • 基于大模型的三叉神经痛预测及治疗方案研究报告
  • window显示驱动开发—使用状态刷新回调函数
  • WebGL图形学总结(二)
  • Spring Boot + MyBatis + Vue:从零到一构建全栈应用
  • linux线程同步
  • P7 QT项目----会学天气预报(完结)
  • 【内存】Linux 内核优化实战 - vm.max_map_count
  • HarmonyOS 6 + 盘古大模型5.5
  • 解决uni-app发布微信小程序主包大小限制为<2M的问题
  • 从服务器收到预料之外的响应。此文件可能已被成功上传。请检查媒体库或刷新本页
  • DAY 37 早停策略和模型权重的保存
  • @annotation:Spring AOP 的“精准定位器“
  • uniapp开发小程序,导出文件打开并保存,实现过程downloadFile下载,openDocument打开
  • 4.文件管理(文本、日志、Excel表)
  • 基于PyQt5和PaddleSpeech的中文语音识别系统设计与实现(Python)