Android应用内存分析与优化 - 工具篇之Booster

在原理篇中,我们发现在App内存的分布中,Code是占大头的部分,所以我们可以从App体积方面想办法,通过减小App体积达到降低内存的目的,同时,根据权威的机构分析,体积与用户下载和留存有很大的联系,总之体积减小有很大的好处,本篇研究了一下滴滴开源的Booster工具,减小包体积,优化App性能。

1. Booster简介

1.1 是什么

Booster 是滴滴开源的一款专门为移动应用设计的易用、轻量级且可扩展的质量优化框架,其目标主要是为了解决随着 APP 复杂度的提升而带来的性能、稳定性、包体积等一系列质量问题。

Booster 提供了性能检测、多线程优化、资源索引内联、资源去冗余、资源压缩、系统 Bug 修复等一系列功能模块,可以使得稳定性能够提升 15% ~ 25%,包体积可以减小 1MB ~ 10MB。

Booster 主要由 Transformer 和 Task 组成,Transformer 主要用于对字节码进行扫描或修改(取决于 Transformer 的功能),Task 主要用于构建过程中的资源处理,为了满足特异的优化需求,Booster 提供了 Transformer SPI and VariantProcessor SPI允许开发者进行定制,以下是 Booster 的整体框架:

1.2 能做什么?

  • 性能检测:使用 Booster 可以发现潜在的性能问题,例如,在应用中调用可能阻塞 UI 线程或者主线程的 API,如,I/O API 等;

  • 性能优化:对于开发者来说,线程管理一直是个头疼的问题,特别是第三方 SDK 中的线程,过多的线程可能会导致内存不足,然而幸运的是,这些问题都能通过 Booster 来解决;

  • 系统问题修复:例如全局性地修复 Android API 25 版本中 Toast 导致的崩溃;

  • 应用瘦身:如,资源压缩及冗余资源删除、资源索引内联及常量删除;

1.3 目前Booster内置的一些功能

  • 动态加载模块支持差异化的优化需求,Booster 实现了模块的动态加载,以便于开发者能在不使用配置的情况下选择使用指定的模块,详见:booster-task-all、booster-transform-all,也可以定制task和transform,然后设置classpath。

  • 第三方类库注入:支持动态添加依赖或者注入某些类和库(比如插桩、无埋点统计等),详见:booster-transform-lint。

  • 多线程优化:业务线众多的 APP 普遍存在线程过载的问题,而线程管理一直是开发者最头疼的问题之一,虽然可以通过制定严格的代码规范来规避此类问题发生而对于第三方 SDK 来说,代码规范则有些力不从心。为了彻底的解决这一问题,Booster 通过在编译期间修改字节码实现了全局线程池优化,并对线程进行重命名。详见:booster-transform-thread。

  • SharedPreferences 优化:SharedPreferences几乎无处不在,而在主线程中修改 SharedPreferences 会导致卡顿甚至 ANR,为了彻底的解决这一问题,Booster 对 APP 中的指令进行了全局的替换。详见:booster-transform-shared-preferences。

  • 常量字段删除:无论是资源索引,还是其它常量字段,在编译完成后,就没有存在的价值了(反射除外),因此,Booster 将对资源索引字段访问的指令替换为常量指令,将其它常量字段从类中删除,一方面可以提升运行时性能,另一方面,还能减小包体积,资源索引(R)表面上看起来微不足道,实际上占用不少空间。

  • 资源压缩:APP 的包体积也是一个非常重要的指标,在 APP 安装中,图片资源占了相当大的比例,通常情况下,图片质量降低 10%-20% 并不会影响视觉效果,因此,Booster 采用有损压缩来降低图片的大小,而且,图像尺寸越小,加载速度越快,占用内存越少。Booster 提供了两种压缩方案:

    • pngquant 有损压缩(需要自行安装 pngquant 命令行工具)

    • cwebp 有损压缩(已内置)

  • 性能检测:APP 的卡顿率是衡量应用运行时性能的一个重要指标,为了能提前发现潜在的卡顿问题,Booster 通过静态分析实现了性能检测,并生成可视化的报告帮助开发者定位问题所在,其实现原理是通过分析所有的 class 文件,构建一个全局的 Call Graph, 然后从 Call Graph 中找出在主线程中调用的链路(Application、四大组件、View、Widget等相关的方法),然后再将这些链路以类为单位分别输出报告,详见:booster-transform-lint。

  • WebView 预加载:为了解决 WebView 初始化导致的卡顿问题,Booster 通过注入指令的方式,在主线程空闲时提前加载 WebView。

2. 引入使用Booster

2.1 地址

  1. 开源地址:https://github.com/didi/booster/tree/master

  2. 官方Doc:https://booster.johnsonlee.io/zh/guide/

2.2 引入

集成 Booster 的最佳方式是集成真正需要的模块来解决项目中遇到的特定问题。

buildscript {ext.boosterVersion = '4.8.0'repositories {google()mavenCentral()// OPTIONAL If you want to use SNAPSHOT version, sonatype repository is required.maven { url 'https://oss.sonatype.org/content/repositories/public' }}dependencies {classpath "com.didiglobal.booster:booster-gradle-plugin:$boosterVersion" // ① booster基础插件// ② 弄清楚真正需要的特性,选择正确的模块进行集成,下面的是我们的工程中目前引入的模块classpath "com.didiglobal.booster:booster-task-compression-cwebp:$boosterVersion" // 采用 cwebp 对资源进行压缩classpath "com.didiglobal.booster:booster-task-compression-processed-res:$boosterVersion" // ap_ 文件压缩classpath "com.didiglobal.booster:booster-task-resource-deredundancy:$boosterVersion" // 去冗余资源classpath "com.didiglobal.booster:booster-transform-r-inline:$boosterVersion" // 资源索引内联classpath "com.didiglobal.booster:booster-transform-thread:$boosterVersion"   // 性能优化解决线程过多问题classpath "com.didiglobal.booster:booster-transform-shared-preferences:$boosterVersion"   // SharedPreferences 优化,解决卡顿问题}
}allprojects {repositories {google()mavenCentral()// OPTIONAL If you want to use SNAPSHOT version, sonatype repository is required.maven { url 'https://oss.sonatype.org/content/repositories/public' }}
}// 在你的 application 工程的build.gradle中引入,如下:
apply plugin: 'com.android.application'
apply plugin: 'com.didiglobal.booster' // ③

2.3 确认是否启用

然后在终端用如下命令来确认 Booster 是否启用:

./gradlew assembleDebug --dry-run

2.4 版本选择

2.4.1 官方文档上说

由于 AGP 8 的不兼容性变更,AGP 7.x 及以下版本已经不再支持,如果你仍在使用 AGP 7.x,请使用 Booster 4.x

大部分基于 Task 的模块在 Booster 5.0.0 中已经不再支持,但是基于 Transform 的模块仍然支持且没有破坏性变更。

详情请参见 [从 Booster 4.x 迁移到 5.x](迁移到 v5.x | Booster

2.4.2 我们的选择

我们使用booster主要是为了减小包体积,其中重要的一项是资源压缩(booster-task-compression-cwebp),测试合适的版本,经过验证,4.8.0版本是能支持的最高版本,再高的版本就会没有我们需要的Task(booster-task-compression-cwebp)。

所以我们选择了能编译过去,并且有我们需要的Task的最高版本 4.8.0。

2.5 功能组件选择

经过查找测试,决定使用以下6个插件进行优化:

  • booster-task-compression-cwebp(采用 cwebp 对资源进行压缩)

  • booster-task-compression-processed-res(ap_ 文件压缩)

  • booster-task-resource-deredundancy(去冗余资源)

  • booster-transform-r-inline(资源索引内联)

  • booster-transform-thread(性能优化解决线程过多问题)

  • booster-transform-shared-preferences(SharedPreferences 优化,解决卡顿问题)

2.6 booster-task-compression-cwebp插件的参数配置

文档说明如下:

Property

Description

Example

booster.task.compression.cwebp.quality

compression quality (the default is 80)

booster.task.compression.cwebp.ignores

ignore wildcards (separated by comma)

mipmap/ic_launcher*,drawable/ic_launcher*

经过实际测试发现

  1. booster.task.compression.cwebp.quality

    1. 发现不生效,查看代码,应该设置为:booster.task.compression.cwebp.option.quality,验证可用;

  2. booster.task.compression.cwebp.ignores

    1. 按文档中写的示例配置不生效;

    2. 经验证,白名单需要遵循以下规则:

      1. 资源名(png图片)后没有点和扩展名,直接文件名结尾

      2. 资源名前应该还有其它字符,但测试未得到正确的结果,需要再研究,现阶段可以使用通配符*

      3. 多个白名单资源以逗号分隔,逗号前后不能有空格

      4. 白名单不能以双引号或单引号包裹

      5. 白名单太长折行时应以反斜杠续行,如下

      6. booster.task.compression.cwebp.ignores=*food_card_bg,*food_\pic_bg_noa,\*frame_fridge_520_36,\*frame_fridge_550_37,\*frame_fridge_777_36
    3. 编译booster源码,打印日志查看:使用带日志的自己打出来的snapshot版的booster插件,看到Cwebp白名单过滤时,传入的资源字符串的形式是“drawable/food_card_bg”,与之前验证出来的pattern规则能对应上。

3. 总结

本文简述了Booster的功能和其引入的方法,然后应用到我们的项目中发现的一些问题及解决方法,其它的暂未进行深入研究,后续可以引入更多的Task或Transform,也可以扩展我们自己的功能。

另外,研究Booster的过程中,发现字节也开源了一个类似的框架ByteX,后续也可以一起研究一下,取长补短,只要是对项目有用的可以逐步引入,没有的功能也可以通过扩展实现。

4. 参考文献

  • 开源地址

  • 官方Doc

  • 滴滴开源 Booster:移动APP质量优化框架

  • 滴滴Booster移动APP质量优化框架 学习之旅

  • Booster 移动 APP 质量优化框架

5.团队介绍

三翼鸟数字化技术平台-定制平台开发」主要负责设计工具的研发,包括营销设计工具、家电VR设计和展示、水电暖通前置设计能力,研发并沉淀素材库,构建家居家装素材库,集成户型库、全品类产品库、设计方案库、生产工艺模型,打造基于户型和风格的AI设计能力,快速生成算量和报价;同时研发了门店设计师中心和项目中心,包括设计师管理能力和项目经理管理能力。实现了场景全生命周期管理,同时为水,空气,厨房等产业提供商机管理工具,从而实现了以场景贯穿的B端C端全流程系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

金属加工液展|切削液展|2025上海金属加工液展览会

2025上海金属加工液展览会 时间:2025年12月2-4日 地点:上海新国际博览中心 2025上海金属加工液展规划30000平方米展览规模,预设展位1200个,将为国内外加工液产业提供一个集“展示、合作、交易、发展”于一体的综合性平台&#…

React学习———Redux 、 React Redux和react-persist

Redux Redux是一个流行的JavaScript状态管理库,通常用于React等前端框架结合使用。Redux 的设计思想是让应用的状态变得可预测、可追踪、易于调试和测试。 Redux的核心l理念 单一数据源:整个应用的状态被存储在一个唯一的Store对象中,所有…

Python字符串常用方法详解

文章目录 Python字符串常用方法详解一、字符串大小写转换方法(常用)1. 基础大小写转换2. 案例:验证码检查(不区分大小写) 二、字符串查找与替换方法1. 查找相关方法2. 替换相关方法 三、字符串判断方法1. 内容判断方法 四、字符串分割与连接方…

MyBatis—动态 SQL

MyBatis—动态 SQL 一、动态 SQL 的核心作用 动态 SQL 主要解决以下问题: 灵活性:根据不同的输入参数生成不同的 SQL 语句(如条件查询、批量操作)。 可维护性:减少重复代码,通过标签化逻辑提高 SQL 可读…

Python机器学习笔记(二十五、算法链与管道)

对于许多机器学习算法,特定数据表示非常重要。首先对数据进行缩放,然后手动合并特征,再利用无监督机器学习来学习特征。因此,大多数机器学习应用不仅需要应用单个算法,而且还需要将许多不同的处理步骤和机器学习模型链接在一起。Pipeline类可以用来简化构建变换和模型链的…

YOLOv3深度解析:多尺度特征融合与实时检测的里程碑

一、YOLOv3的诞生:继承与突破的起点 YOLOv3作为YOLO系列的第三代算法,于2018年由Joseph Redmon等人提出。它在YOLOv2的基础上,针对小目标检测精度低、多类别标签预测受限等问题进行了系统性改进。通过引入多尺度特征图检测、残差网络架构和独…

已解决(亲测有效!):安装部署Docker Deskpot之后启动出现Docker Engine Stopped!

文章目录 已解决:安装部署Docker Deskpot之后启动出现Docker Engine Stopped!个人环境介绍自己的解决问题思路(详细过程附截图)1.打开控制面板2.点击程序和功能3.点击启动或关闭windows功能4.Hyper-V5.右键菜单栏的windows图标点击…

PCIE接收端检测机制分析

PCIE接收端检测机制分析 1、PCIE的接收端检测机制 接收器检测电路作为发射器的一部分实现,必须正确检测是否存在与ZRX-DC参数(40Ω-60Ω)隐含的直流阻抗等效的负载阻抗。 接收器检测序列的推荐行为如下: ‌初始状态‌&#xff…

[模型部署] 3. 性能优化

👋 你好!这里有实用干货与深度分享✨✨ 若有帮助,欢迎:​ 👍 点赞 | ⭐ 收藏 | 💬 评论 | ➕ 关注 ,解锁更多精彩!​ 📁 收藏专栏即可第一时间获取最新推送🔔…

InternVL3: 利用AI处理文本、图像、视频、OCR和数据分析

InternVL3推动了视觉-语言理解、推理和感知的边界。 在其前身InternVL 2.5的基础上,这个新版本引入了工具使用、GUI代理操作、3D视觉和工业图像分析方面的突破性能力。 让我们来分析一下是什么让InternVL3成为游戏规则的改变者 — 以及今天你如何开始尝试使用它。 InternVL…

鸿蒙 ArkUI - ArkTS 组件 官方 UI组件 合集

ArkUI 组件速查表 鸿蒙应用开发页面上需要实现的 UI 功能组件如果在这 100 多个组件里都找不到,那就需要组合造轮子了 使用技巧:先判断需要实现的组件大方向,比如“选择”、“文本”、“信息”等,或者是某种形状比如“块”、“图…

HTTP GET报文解读

考虑当浏览器发送一个HTTP GET报文时,通过Wireshark 俘获到下列ASCII字符串: GET /cs453/index.html HTTP/1.1 Host: gaia.cs.umass.edu User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) Acc…

【Linux网络】数据链路层

数据链路层 用于两个设备(同一种数据链路节点)之间进行传递。 认识以太网 “以太网” 不是一种具体的网络,而是一种技术标准;既包含了数据链路层的内容,也包含了一些物理层的内容。例如:规定了网络拓扑结…

【打破信息差】萌新认识与入门算法竞赛

阅前须知 XCPC萌新互助进步群2️⃣:174495261 博客主页:resot (关注resot谢谢喵) 针对具体问题,应当进行具体分析;并无放之四海而皆准的方法可适用于所有人。本人尊重并支持每位学习者对最佳学习路径的自主选择。本篇所列训练方…

logrotate按文件大小进行日志切割

✅ 编写logrotate文件,进行自定义切割方式 adminip-127-0-0-1:/data/test$ cat /etc/logrotate.d/test /data/test/test.log {size 1024M #文件达到1G就切割rotate 100 #保留100个文件compressdelaycompressmissingoknotifemptycopytruncate #这个情况服务不用…

2025认证杯二阶段C题完整论文讲解+多模型对比

基于延迟估计与多模型预测的化工生产过程不合格事件预警方法研究 摘要 化工生产过程中,污染物浓度如SO₂和H₂S对生产过程的控制至关重要。本文旨在通过数据分析与模型预测,提出一种基于延迟估计与特征提取的多模型预测方法,优化阈值设置&a…

前端精度问题全解析:用“挖掘机”快速“填平精度坑”的完美解决方案

写在前面 “为什么我的计算在 React Native 中总是出现奇怪的精度问题?” —— 这可能是许多开发者在作前端程序猿的朋友们都会遇到的第一个头疼问题。本文将深入探讨前端精度问题的根源,我将以RN为例,并提供一系列实用解决方案,让你的应用告别计算误差。 一、精度问题的…

2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛) 解题报告 | 珂学家

前言 题解 2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)。 国赛比省赛难一些,做得汗流浃背,T_T. RC-u1 大家一起查作弊 分值: 15分 这题真的太有意思,看看描述 在今年的睿抗比赛上,有同学的提交代码如下&#xff1…

hghac和hgproxy版本升级相关操作和注意事项

文章目录 环境文档用途详细信息 环境 系统平台:N/A 版本:4.5.6,4.5.7,4.5.8 文档用途 本文档用于高可用集群环境中hghac组件和hgproxy组件替换和升级操作 详细信息 1.关闭服务 所有数据节点都执行 1、关闭hgproxy服务 [roothgdb01 tools]# system…

userfaultfd内核线程D状态问题排查

问题现象 运维反应机器上出现了很多D状态进程,也kill不掉,然后将现场保留下来进行排查。 排查过程 都是内核线程,先看下内核栈D在哪了,发现D在了userfaultfd的pagefault流程。 uffd知识补充 uffd探究 uffd在firecracker与e2b的架构下使…