【问题分析】Android 5.0版本SystemUI反复发生ANR crash

问题描述

Android 5.0版本上按照下述的步骤, 会触发SystemUI进程反复ANR然后crash的问题

 

1.       下拉systemui面板

2.       adb –host shell

3.       ps –ax systemui

4.       kill -SIGSTOP <systemui pid>

5.       然后在systemui面板中不停触摸,由于systemui 已经stop 所以会触发一次ANR,紧接着就进一步触发本问题中提到的systemui 反复ANR,AMS 反复restart system

 

Root Cause分析:

 

 

如上面的ANR 时序分析图所示,  导致问题的关键步骤是InputMonitor模块处理notifyANR过程中

longtimeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(...

这里timeout的返回值会被InputDispacther模块作为下一次超时判断的计算变量,AMS 返回的timeout 单位是ms,而InputDispatcher模块中使用的单位是nanos,差别为10^6级别.  InputMonitor模块没有及时将ms级别的timeout转换成nanos,就直接将timeout值送回InputDispacther了(实际上这里的timeout要求下次检查时间超时等待为8秒钟)

最终导致InputDispatcher模块错误的将一个ms级别的timout(没有在换算成为nano second,差了10^6级别)值去计算下一次事件超时等待时间

mInputTargetWaitTimeoutTime= now() + newTimeout;

从而导致systemui 还没有足够的时间去重新启动(本来应用有8秒超时等待时间),而下一次InputDispatcher dispatchOnce调用马上发生事件派发超时,进而导致重复发生了 ANR kill systemui 的时序过程

 

解决方案

 

try {
    // Notify the activity manager about the timeout and let it decide whether
    // to abort dispatching or keep waiting.
    long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
               windowState.mSession.mPid, aboveSystem, reason);
    if (timeout >= 0) {
        // The activity manager declined to abort dispatching.
        // Wait a bit longer and timeout again later.
        return timeout * 1000000L; // nanoseconds
    }
 } catch (RemoteException ex) {
 }


如上图所示, 在<AOSP>/framework/base/services/core/java/com/android/server/wm/InputMonitor.java 的notifyANR 函数中将return 的timeout  (ms) 乘以 1000000换算为nanosecond再进行返回. Google 在后续的Android 版本中已经按照这个方式做了fix

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值