Android卡顿优化--卡顿检测

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

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)网站:GitHub - markzhai/AndroidPerformanceMonitor: A transparent ui-block detection library for Android. (known as BlockCanary)

使用:

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

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值