背景:
昨天有相关学员朋友一直在vip群里提出他的一个ANR问题,一直说自己分析这个ANR完全没有相关的头绪

针对这个ANR问题,我与该学员沟通了解情况后,发现他这种anr问题明显不是常规的那种app某个地方执行耗时导致的卡顿,所以常规那种抓取anr trace来分析定位的套路明显就不行了。
那么他这个anr到底是怎么复现的呢,具体是个啥情况呢?今天马哥来给大家在aosp14上复现该ANR问题然后先提供给大家作为一个课程作业进行完成哈,答案后期会blog或者vip群分享方式给大家。
问题复现:
需要复现该问题,其实需要对系统正常的相关源码进行一些修改才可以,学员朋友也是一样,他修改了相关源码引入了ANR问题,但是又不知道怎么引入的。
修改代码如下:
frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 093c09fff995..98a84557dbe7 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -327,10 +327,10 @@ public class ScreenshotView extends FrameLayout implements
}
return touchRegion;
}
-
+ static int count = 0;
private void startInputListening() {
- stopInputListening();
- mInputMonitor = new InputMonitorCompat("Screenshot", mDefaultDisplay);
+ // stopInputListening();
+ mInputMonitor = new InputMonitorCompat("Screenshot " +(count++), mDefaultDisplay);
mInputEventReceiver = mInputMonitor.getInputReceiver(
Looper.getMainLooper(), Choreographer.getInstance(), ev -> {
if (ev instanceof MotionEvent) {
@@ -345,14 +345,14 @@ public class ScreenshotView extends FrameLayout implements
}
void stopInputListening() {
- if (mInputMonitor != null) {
- mInputMonitor.dispose();
- mInputMonitor = null;
- }
- if (mInputEventReceiver != null) {
- mInputEventReceiver.dispose();
- mInputEventReceiver = null;
- }
+// if (mInputMonitor != null) {
+// mInputMonitor.dispose();
+// mInputMonitor = null;
+// }
+// if (mInputEventReceiver != null) {
+// mInputEventReceiver.dispose();
+// mInputEventReceiver = null;
+// }
}
简单概述一下修改:
1、针对new InputMonitorCompat和InputEventReceiver前不想进行stopInputListening()调用
2、同时让stopInputListening()方法其他地方也不要调用
即ScreenshotView一旦创建了相关的InputMonitor就不希望它自我销毁掉,会一直存在。
其实看上面修改表面上也没啥问题,就相当于多了一个全局事件监听者InputMonitor会一直监听系统事件而已。
复现ANR步骤
第一步触发截图:
上面修改完成后进行编译运行,但是需要让系统运行到让这个ScreenshotView展示,就需要触发系统截图
这里大家实体机的话可以用组合键截图等,模拟器的话建议就用模拟key事件来截图,截图按键命令:
adb shell input keyevent 120
执行后就会发现有截图动作和窗口产生

看到这个后说明ScreenshotView相关的InputMonitor已经注册,如果不放心可以用dumpsys命令确认一下:
adb shell dumpsys input | grep Screenshot
Reason: [Gesture Monitor] Screenshot 0 (server) is not responding. Waited 5000ms for MotionEvent(deviceId=4, eventTime=55126095000, source=TOUCHSCREEN | STYLUS | BLUETOOTH_STYLUS, displayId=0, action=MOVE, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=22.8, yPrecision=11.1, xCursorPosition=nan, yCursorPosition=nan, pointers=[0: (844.0, 2242.9)]), policyFlags=0x62000000
Window: [Gesture Monitor] Screenshot 0 - [Gesture Monitor] Screenshot 0
1: name='[Gesture Monitor] Screenshot 0', id=110, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY | SPY, alpha=1.00, frame=[0,0][0,0], globalScale=1.000000, applicationInfo.name=[Gesture Monitor] Screenshot 0, applicationInfo.token=<null>, touchableRegion=[-14399,-29599][14400,29600], ownerPid=1965, ownerUid=10111, dispatchingTimeout=5000ms, hasToken=0x73a263ddddd0, touchOcclusionMode=BLOCK_UNTRUSTED
559: channelName='[Gesture Monitor] Screenshot 0 (server)', windowName='[Gesture Monitor] Screenshot 0 (server)', status=NORMAL, monitor=false, responsive=false
第二步操作:
不断在手机模拟器进行相关的触摸点击操作直到anr产生(预计1分钟以内既可以)

作业要求:
1、要求可以按上面步骤产生出anr
2、分析出anr的原因
更多framework实战干货,请关注下面“千里马学框架”

2426

被折叠的 条评论
为什么被折叠?



