Android卡顿优化实战

1.卡顿的定义

如果在一个Vsync周期内(60HZ的屏幕上就是16.6ms),按照整个上帧显示的执行的顺序来看,应用UI线程的绘制、RenderThread线程的渲染、SurfaceFlinger/HWC的图层合成以及最终屏幕上的显示这些动作没有全部都执行完成的话,屏幕上就会显示上一帧画面的内容,也就是掉帧,而人的肉眼就可能会感觉到画面卡顿。

2.卡顿监控定位问题
线下监控工具
  • 2.1 BlockCanary: 动态检测消息执行耗时。

基于消息机制,向Looper中设置Printer,监控dispatcher到finish之间的操作,满足耗时阀值dump堆栈、设备信息,以通知形式弹出卡顿信息以供分析。

其中最核心的两步是在调用msg.target.dispatchMessage(msg),进行消息的分发前记录时间T1,调用msg.target.dispatchMessage(msg)进行消息分发后记录时间T2,如果T2-T1大于设置的卡顿阈值就会打印当前方法调用堆栈以及显示其他相关提示或打印日志;
blockcanary充分的利用了Loop的机制,在MainLooper的loop方法中执行dispatchMessage前后都会执行printer的println进行输出,并且提供了方法设置printer。通过分析前后打印的时差与阈值进行比对,从而判定是否卡顿。

创建AppBlockCanaryContext:

class AppBlockCanaryContext : BlockCanaryContext() {
}

在application中初始化blockCanary:

BlockCanary.install(this, AppBlockCanaryContext()).start()

BlockCanary会在发生卡顿(通过MonitorEnv的getConfigBlockThreshold设置)的时候记录各种信息,输出到配置目录下的文件,并弹出消息栏通知(可关闭)。

dump的信息包括:

基本信息:安装包标示、机型、api等级、uid、CPU内核数、进程名、内存、版本号等
耗时信息:实际耗时、主线程时钟耗时、卡顿开始时间和结束时间
CPU信息:时间段内CPU是否忙,时间段内的系统CPU/应用CPU占比,I/O占CPU使用率
堆栈信息:发生卡慢前的最近堆栈,可以用来定位卡慢发生的地方和重现路径

  • 2.2 滴滴Dokit接入

接入文档

帧率检测:帧率信息提供波形图查看功能,让帧率监控的趋势更加明显。


CPU检测:CPU 使用率信息提供波形图查看功能,让 CPU 监控的趋势更加形象。


卡顿检测:我们做App开发时,可能会遇到卡顿的情况,往往会忽略,而且复现时出现卡顿的概率也挺挺小的。而卡顿功能帮助我们把App出现的卡顿记录下来,锁定 App 出现卡顿的时刻,打印出对应的代码调用堆栈。


阿里开源工具Solopi监测实战

使用阿里巴巴公司开源性能测试工具SoloPi。

Github主页地址: https://github.com/alipay/SoloPi

工具下载地址:https://github.com/alipay/SoloPi/releases/tag/v0.12.0

帧率测试标准:
测试内容 测试描述 通过标准
应用冷启动完成时间 记录应用开始启动到进入界面的时间 中高端机:1500ms 低端机:3500ms
界面滑动过程平均刷新帧率 测试应用界面内滑动时的平均帧率 最高帧为目标帧率(需识别出当前界面最高帧),平均帧与目标帧之差不能超过5%,std<5%
界面滑动过程连续丢帧数 进入被测界面先滑动等界面所有数据加载完成了再测试 连续丢帧不能超过3帧
CPU占用标准
测试内容 测试描述 通过标准
测试亮屏情况下后台应用对CPU的占用情况 测试应用切换到后台亮屏状态下应用CPU占用 统计10分钟的均值不超过3%
测试灭屏情况下后台应用对CPU的占用情况 测试应用切换到后台灭屏状态下应用CPU占用 统计10分钟的均值不超过2%

然后找到我们的目标App,进行如上指标测试。


2.4 Androidstudio Profile 卡顿定位实战

见另一篇文章链接:https://www.jianshu.com/p/7186982ef3a4

2.5 线上监控工具

基调听云APM(应用性能管理)产品能够提供代码级性能监控并对故障快速定位,能够兼容OpenTelemetry框架实现全量采集,支持微服务架构下的应用性能监控和治理。

大致工作流程:
1、首先在客户端(Android、iOS、Web等)采集数据;
2、接着将采集到的数据整理上报到服务器;
3、服务器接收到数据后建模、存储、挖掘分析,让后将数据可视化,供用户使用。

Android APM 的原理其实非常简单,用一句话总结就是:

依据打包原理,在 class 转换为 dex 的过程中,调用 gradle transform api 遍历 class 文件,借助 Javassist、ASM 等框架修改字节码,插入我们自己的代码实现性能数据的统计。以上所有过程都是在编译期完成的。

3.卡顿优化处理方案

  • 应用UI线程耗时引起卡顿

例如在页面加载初始化时,View加载上,view点击事件上,adapter的bindViewholder上这些地方,做了UI线程的耗时操作,引起卡顿。

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 模拟耗时操作
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 执行UI操作
        TextView textView = findViewById(R.id.textView);
        textView.setText("Task completed!");
    }
});

优化建议:使用异步任务或线程池来执行耗时操作,以避免阻塞UI线程。比如
在异步任务做,使用协程切子线程操作。

  • 频繁的内存分配和释放:
for (int i = 0; i < 1000; i++) {
    String result = expensiveOperation();
    // 执行其他操作
}

private String expensiveOperation() {
    // 模拟耗时操作
    try {
        Thread.sleep(10);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "result";
}

优化建议:避免在循环中频繁创建和释放对象,尽量复用对象或使用对象池。

// 优化示例:复用对象
private StringBuilder stringBuilder = new StringBuilder();

for (int i = 0; i < 1000; i++) {
    stringBuilder.setLength(0); // 清空StringBuilder
    expensiveOperation(stringBuilder);
    String result = stringBuilder.toString();
    // 执行其他操作
}

private void expensiveOperation(StringBuilder stringBuilder) {
    // 模拟耗时操作
    try {
        Thread.sleep(10);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    stringBuilder.append("result");
}
参考:

https://mp.weixin.qq.com/s/ff1l-80htFoU3xoH8O49zg
https://www.jianshu.com/p/03dd61816051
https://mp.weixin.qq.com/s/v618ky870WWr5RqoE5_U3Q
https://zhuanlan.zhihu.com/p/533348005

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容