Android卡顿优化工具

线上监控的方案

1、BlockCanary

从Choregrapher中可以知道,帧的渲染是通过消息发送到主线程执行的。所以通过在计算msg的处理时间就可以判定是否发生卡顿。

Looper.java

public static void loop() {
    ...
    for (;;) {
        ...
        // This must be in a local variable, in case a UI event sets the logger
        Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }
        msg.target.dispatchMessage(msg);
        if (logging != null) {
            logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
        }
        ...
    }
}

BlockCanary主要是检测msg.target.dispatchMessage(msg);之前的>>>>> Dispatching to 和之后的<<<<< Finished to的间隔时间。 应用发生卡顿,一定是在dispatchMessage中执行了耗时操作。通过给主线程的Looper设置一个Printer,打点统计dispatchMessage方法执行的时间,如果超出阀值,表示发生卡顿,则dump出各种信息,提供开发者分析性能瓶颈。

2、Matrix

帧率监控
向 Choreographer 注册监听,在每一帧 doframe 回调时判断距离上一帧的时间差是否超出阈值(卡顿),若是超出阈值,则获取数组 index 前的全部数据(即两帧之间的全部函数执行信息)进行分析上报。

慢函数,Anr监控
和BlockCannary一样是通过Looper的printer获取msg的执行时间

Matrix还对方法进行了插桩,对每个方法可以更详细的分析

线下工具

1、Perfetto

Perfetto是基于Android 9(P)起可用的平台级跟踪工具,但仅从Android 11(R)起默认启用。在Android 9(P)和10(Q)上,我们首先需要开启traced和traced_probes这两个进程,才能使用Perfetto来抓取数据,可通过命令行来开启手机的这两个进程

adb shell setprop persist.traced.enable 1
  1. 在开发者选项中打开

  2. 命令行工具抓取

    adb shell perfetto --config :test --out /data/misc/perfetto-traces/trace

查看

在Chrome打开 https://ui.perfetto.dev/#!/

2、Systrace

命令行:systrace.py -t 10 sched gfx view wm am app webview -o mytrace.html -a com.androidtrace.test

具体参数含义如下:

  • -t:指定统计时间为20s。
  • shced:cpu调度信息。
  • gfx:图形信息。
  • view:视图。
  • wm:窗口管理。
  • am:活动管理。
  • app:应用信息。
  • webview:webview信息。
  • -a:指定目标应用程序的包名。
  • -o:生成的systrace.html文件。

查看丢帧

丢帧.png

查看主线程状态

绿色:运行状态

橙色:IO阻塞

蓝色:系统资源不足

灰色:锁

紫色:频繁创建对象

3、Profiler
Profiler查看函数耗时非常方便,缺点是开销大,可能带偏方向

Call Chart可以清晰的看到具体的方法调用情况和执行时间

call chart.png

Bottom Up根据方法耗时排序

bottom up

4、TraceView
TraceView需要手动埋点,生成的trace文件,路径在sdcard/Android/data/项目包名/files。拿到trace文件后用profiler分析和上面是一样的

//开始埋点,“app”是最后生成的性能分析文件
Debug.startMethodTracing("App");

//埋点结束,期间start 到 stop 之间的代码,就是你要测试的代码范围
Debug.stopMethodTracing();

5、StrictMode
线程策略的检测内容,是一些自定义的耗时调用、磁盘读取操作以及网络请求等

虚拟机策略的检测内容:Activity泄露,Sqlite泄露,检测实例数量

        // 设置线程策略
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectCustomSlowCalls() //API等级11,使用StrictMode.noteSlowCode
                .detectDiskReads()
                .detectDiskWrites()
                .detectNetwork() // or .detectAll() for all detectable problems
                .penaltyLog() //在Logcat 中打印违规异常信息
//              .penaltyDialog() //也可以直接跳出警报dialog
//              .penaltyDeath() //或者直接崩溃
                .build());
        //设置虚拟机策略
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectLeakedSqlLiteObjects()
                // 给NewsItem对象的实例数量限制为1
                .setClassInstanceLimit(NewsItem.class, 1)
                .detectLeakedClosableObjects() //API等级11
                .penaltyLog()
                .build());

版权声明:
作者:zhangchen
链接:https://www.techfm.club/p/50023.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>