卡顿问题检测,分:自动化卡顿检测方案 和 卡顿单点问题检测方案 两种。
1 自动化卡顿检测方案
为什么需要自动化检测方案?
(1)系统工具适合线下针对性分析
(2)线上及测试环节需要自动化检测方案
方案的原理
(1)消息处理机制,一个线程只有一个Looper
(2)mLogging对象在每个message处理前后被调用
(3)主线程发生卡顿,是在dispatchMessage执行耗时操作
// 代码如下:
public final class Looper {
public static void loop() {
//...
for (;;) {
//...
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
//... message 处理代码
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
//...
}
}
}
AndroidPerformanceMonitor
(1)非侵入式的性能监控组件,通知形式弹出卡顿信息
(2)这个组件的原理,就是上面卡顿监控的原理。
使用:
(1)加入依赖:
implementation 'com.github.markzhai:blockcanary-android:1.5.0'
(2)在 Application 的 onCreate() 中添加下面代码:
BlockCanary.install(this, new AppBlockCanaryContext()).start();
测试:
在 MainActivity 的 onCreate() 中延时两秒,结果如下:
总结:
(1)非侵入式
(2)方便精准,定位到代码每一行
自动检测方案问题
(1)确实卡顿了,但卡顿堆栈可能不准确
(2)和OOM一样,最后的堆栈只是表象,不是真正的问题
检测方案优化
2 卡顿单点问题检测方案
背景:为什么要检测卡顿的单点问题呢?
(1)自动卡顿检测方案并不够满足所有场景,(如:所有的message都能在规定时间内执行完,但是用户就是觉得卡顿)
(2)体系化解决方案,务必需要尽早暴露问题
(3)单点问题:主线程IPC,DB
IPC问题检测
检测指标:
(1)IPC调度类型
(2)调用耗时,次数
(3)调用堆栈,发生线程
(1)常规方案:
(1)前后加上埋点
(2)不够优雅,容易忘记
(3)维护成本大
IPC问题监测技巧:
(1)ADB命令:
// 开始:
adb shell am trace-ipc start
// 结束:
adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc-trace.txt
// 导出来
adb shell /data/local/tmp/ipc-trace.txt
(2)优雅实现方案
使用 ARTHook 还是 AspectJ ?
(1)ARTHook :可以Hook系统方法
(2)AspectJ:非系统方法
添加到 Application 的 onCreate() 方法中:
// ARTHook实现,对应视频的6-5节
try {
DexposedBridge.findAndHookMethod(Class.forName("android.os.BinderProxy"), "transact",
int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
LogUtils.i( "BinderProxy beforeHookedMethod " + param.thisObject.getClass().getSimpleName()
+ "\n" + Log.getStackTraceString(new Throwable()));
super.beforeHookedMethod(param);
}
});
} catch (ClassNotFoundException e) {
e.printStackTrace();
}