Android卡顿优化--卡顿检测
发布日期:2021-05-06 19:10:13 浏览次数:44 分类:精选文章

本文共 2352 字,大约阅读时间需要 7 分钟。

卡顿问题检测,分:自动化卡顿检测方案 和 卡顿单点问题检测方案 两种。

 

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)这个组件的原理,就是上面卡顿监控的原理。

(3)网站:,

 

使用:

(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();        }

 

 

 

 

上一篇:Android卡顿优化--ANR
下一篇:Android卡顿优化--概览

发表评论

最新留言

很好
[***.229.124.182]2025年04月04日 18时01分00秒