IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 卡顿,ANR分析 -> 正文阅读

[移动开发]Android 卡顿,ANR分析

自动化检测卡顿方法

CPU Profiler 和 Systrace 都是适合线下使用的,无法带到线上。那我们如何做到线上监测卡顿呢?

我们都知道一个进程中只有个Looper对象,我们通过查看Looper源码发现,在其loop方法中的死循环中有个mLogging对象,在执行的时候打印了一个Dispatching to日志,执行完成的时候有打印了一个Finished to日志。如:

public static void loop() {

       // ....省略开始代码...

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
?
            // This must be in a local variable, in case a UI event sets the logger
            final Printer logging = me.mLogging;
            if (logging != null) {
                //重点 开始打印
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            // ...省略中间代码...

            if (logging != null) {
                //重点 完成打印
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }
?
            // ...省略最后代码...
        }
    }

所以我们可以自定义Printer对象,让Handler的日志都通过我们自定义的Printer进行打印,然后收集日志信息,匹配Dispatching to和Finished to字段,如果在设定的某个时间内只有Dispatching to字段而没有Finished to字段,那么就说明发生了卡顿。发生卡顿后我们就收集此时的调用栈信息。相反如果两个字段都存在则说明应用运行的很流畅。

字段Printer设置给mLogging对象:

Looper.getMainLooper().setMessageLogging(new Printer() {
    @Override
    public void println(String log) {
          Log.e("printer","==println=="+log);
    }
});

代码中的log字段就是我们需要的Dispatch和Finished字段,我们监测这两个字段并收集调用栈信息将其发送到后端进行分析使用。

那么这里其实还存在一个问题就是可能我们收集的信息不够准确,为什么呢?就是我们收集的调用栈信息是最后收集的,那么这个时候有可能卡顿已经执行完成了,此刻搜集到的信息有可能不是卡顿发生的关键信息。就像OOM一样,它是一个随时都有可能发生的。所以我们需要高频率的收集日志信息,高频率的收集对后端有一定的压力,而我们高频收集的信息有很大一部分也是重复的,所以就需要日志去重操作。

检测卡顿框架ANR-WatchDog

ANR-WatchDog
WatchDog原理是:创建一个监测线程,该线程不断往UI线程post一个任务,然后睡眠固定时间,等该线程重新起来后检测之前post的任务是否执行了,如果任务未被执行,则生成ANRError,并终止进程。

发生ANR到弹框在不同的组件之间时间定义是不一样的,按键是5秒。前台广播10秒,后台广播60秒。前台服务20秒,后台服务200秒。这些数据都定义在AMS中

其他
CPU Profile
目前Android Studio以及自带了CPU Profiler工具,它可以以图形化的形式展示执行的时间、调用栈等信息。收集的信息比较全面,包含了所有线程。但是由于其收集信息全面,导致了运行时内存开销严重,App函数整体运行都会变慢,可能会带偏我们的优化方向。

使用方式: Debug.startMethodTracing(); … Debug.stopMethodTracing(); 最终生成的文件在sd卡:Android/data/packagename/files目录下。

Systrace
Systrace之前文章已经讲解过,它是轻量级的框架,而且开销小,可以直观反映CPU的利用率而且右侧alter可以针对一些问题给出相关的建议。 比如绘制慢或者GC频繁等。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-26 08:57:51  更:2021-11-26 08:59:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:08:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码