Android APK体积优化(瘦身)
1、基础知识:
1.1 apk结构
lib :存放so文件,对应不同的cpu架构
res :资源文件,layout、drawable等,经过aapt编译
assets :资源文件,不经过aapt编译
classes.dex :dx编译后的java文件,可执行文件,可以直接在Android系统中运行
resources.arsc :二进制资源文件,经过aapt打包res目录下的文件后生成的文件
META-INF :签名信息相关文件
CERT.RSA :签名文件,存放公钥和加密算法描述
CERT.SF :摘要加密,存放加密文件,是使用私钥对摘要明文加密后得到的密文信息,只有使用与私钥配对的公钥才能解密该文件
MANIFEST.MF :文件摘要,存放程序清单文件,包含包中所有文件的摘要明文
AndroidManifest.xml :清单文件,包含组件的声明和配置
kotlin :编译后的kotlin文件

1.2 apk打包流程
精简:资源文件、Java文件 > dex文件 > APK

2、优化方案
2.1 常规操作
2.1.1 图片体积压缩
1)tinypng压缩工具,在线压缩、AS插件
2)Webp格式,png格式转Webp格式,AS支持一件转换

3)图片着色器
针对相同图片不同颜色的处理,原本使用两个icon切换,可以使用android:tint=""代替
<ImageViewandroid:layout_width="100dp"android:layout_height="100dp"android:src="@drawable/img_fallback"android:tint="@color/color_000000_FFFFFF"/>
2.1.2 开启混淆
buildTypes {release {minifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}
}
注意:minifyEnabled true 默认启用R8代码缩减功能,慎用R8,会忽略视图修改默认优化行为的所有ProGuard规则,如:-optimizations 和 -optimizationpasses
解决方案:开启混淆,但不启用R8
android.enableR8=false
android.enableR8.libraries=false
2.1.3 资源缩减
1)Lint检测工具
- 检测无用的资源文件
AS Analyze -> Run Inspection by Name -> Unused resources
注意:这种方式不一定准确,如:有些图片,SDK有引用,但是在本地代码中检测不出来引用的地方。


检测结果:

- 检测
2)资源文件缩减
假如一些资源文件不确实是否还在使用,或者不确定需求是否变更,不敢删除,先留着。这情况可以使用shrinkResources来缩减资源。
buildTypes {release {minifyEnabled true // 开启混淆shrinkResources true // 资源缩减proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}
}
注意:要配合minifyEnabled一起使用,原理:先代码移除,然后引用的资源变成无用,才可以进一步缩减。
3)so文件缩减
一般集成第三方SDK时,会提供各种架构的so文件,可以做相应的剔除
- 目前市面上手机cpu架构以arm架构为主,所以只保留arm的一种so文件即可,armeabi、armeabi-v7a的壳直接删除
- 如果需要模拟器调试,可以加上x86架构
android {defaultConfig {ndk {abiFilters 'armeabi-v7a'}}
}
4)移除未使用的备用资源
- 多语言项目,配置支持的语言
defaultConfig {resConfigs("en", "zh", "zh-rCN")
}
- 资源文件,限制使用的目录
defaultConfig {resConfigs("xxhdpi", "xxxhdpi")
}
2.2 进阶
2.2.1 resources资源混淆
资源混淆就是将原本冗长的资源路径变短,如:res/drawable/abc 变成 r/d/a。开源工具AndResGuard
2.2.2 ReDex
dex文件是打包中的产物,redex是facebook开源的分包优化方案。
2.2.3 so动态加载
so文件按需加载,利用插件化的思想。
注意:风险大,要考虑周全,如:下载时机、网络环境、加载失败后的策略。
2.2.4 插件化
按需加载
2.3 高级
2.3.1 图片网络化
将图片放到服务器,通过动态下载的方式减小apk体积。
弊端:首次加载图片,依赖网络环境
注意:如果比较在意流量、加载速度,需要权衡
2.3.2 原生 -> H5
如促销活动,需要加载大量图片,且原生不够动态化,可以使用H5来实现
2.3.3 修改第三方库,剔除不需要的代码
对于引用的第三方库,往往只是用到了其中某一两项功能,对于多余的功能,可以考虑剔除。
注意:版本升级的时候,要注意
2.3.4 DebugItem
DebugItem里主要包含两种信息:
- 调试信息,函数的参数变量和所以的局部变量
- 排查问题信息,所有的指令集行号和源文件行号的对应关系
注意:去除debug信息和行号信息,不是极致,不推荐
2.3.5 R Field内联
可以解决R文件过多导致MultiDex 65535的问题,进一步对代码瘦身,
参考:字节的shrink-r-plugin,滴滴的booster
2.3.6 减少ENUM使用
没减少一个ENUM,大约可以减少1-1.4kb的大小
3、总结
任重道远 …
相关文章:
Android APK体积优化(瘦身)
1、基础知识: 1.1 apk结构 lib :存放so文件,对应不同的cpu架构 res :资源文件,layout、drawable等,经过aapt编译 assets :资源文件,不经过aapt编译 classes.dex :dx编译…...
python技术栈 之 单元测试中mock的使用
一、什么是mock? mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。 二、mock的作用 特别是开发过程中上下游未完成的工序导致当前无法测试,需要虚拟某些特定对象…...
python 提取冒号和逗号内的字符串
如果你想要从字符串中提取冒号和逗号之间的内容,你可以使用正则表达式来完成。以下是使用 Python 的re模块进行提取的示例: import retext 这是一个包含:冒号,逗号:的字符串# 使用正则表达式匹配冒号和逗号之间的内容 pattern r[:](.*?)[,] matches …...
CentOS安装Postgresql
PG基本安装步骤 安装postgresql: sudo yum install postgresql-server初始化数据库:安装完毕后,需要初始化数据库并创建初始用户: sudo postgresql-setup initdb启动和停止服务: sudo systemctl start postgresql sudo…...
云原生可观测框架 OpenTelemetry 基础知识(架构/分布式追踪/指标/日志/采样/收集器)...
什么是 OpenTelemetry? OpenTelemetry 是一个开源的可观测性框架,由云原生基金会(CNCF)托管。它是 OpenCensus 和 OpenTracing 项目的合并。旨在为所有类型的可观测信号(如跟踪、指标和日志)提供单一标准。 https://opentelemetry.iohttps://www.cncf.io…...
多用户跨境电商商品库系统快速搭建(全开源)
搭建一个多用户跨境电商商品库系统需要以下步骤: 1. 确定系统需求:首先,需要明确系统的功能需求,包括商品管理、订单管理、用户管理、支付管理等。根据具体需求确定系统的功能和界面设计。 2. 确定技术栈:选择合适的…...
DataGrip 配置 HiveServer2 远程连接访问
文章目录 集群配置 HiveServer2 服务DataGrip 配置 HiveServer2 访问 Hive 集群配置 HiveServer2 服务 1.在 Hive 的配置文件 hive-site.xml 中添加如下参数: <!-- 指定 HiveServer2 运行端口,默认为:10000 --><property><na…...
异常的使用
第一章 异常 1、异常概念 异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响,在程序中的意思就是: 异常:指的是程序…...
软件安全测试包含哪些内容和方法?安全测试报告的必要性
软件安全测试是一种通过模拟真实攻击的方式,对软件系统进行全面的安全性评估和测试,以发现潜在的安全漏洞和弱点,是确保软件系统安全性的重要措施。在进行软件安全测试时,我们需要了解测试的内容和方法,以及为什么进行…...
【代码随想录-leetcode第四题 20.有效的括号】
题目描述 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右…...
造个轮子-任务调度执行小框架-IOC容器实现
文章目录 前言使用场景特性项目结构初始化执行流程可替换核心组件容器创建扫描目标包容器实例BeanDefinitionMap 创建过滤并初始化创建对象依赖注入完整代码前言 忙里偷闲,今天终于是把概率论这块骨头干下来了。所以的话,留了点时间,把整个项目的结构和基本的功能给实现以下…...
npm发包中一些操作备忘
1、npm发布相关命令 发布 npm publish 发布beta版 npm publish --tag beta 取消发布 npm unpublish --force 2、lerna发布相关命令 发布 lerna publish 其他的的官方文档里面比较全 lerna中文文档...
15_基于Flink将pulsar数据写入到ClickHouse
3.8.基于Flink将数据写入到ClickHouse 编写Flink完成数据写入到ClickHouse操作, 后续基于CK完成指标统计操作 3.8.1.ClickHouse基本介绍 ClickHouse 是俄罗斯的Yandex于2016年开源的列式存储数据库(DBMS),使用C语言编写,主要用…...
Pycharm如何打断点进行调试?
断点调试,是编写程序中一个很重要的步骤,有些简单的程序使用print语句就可看出问题,而比较复杂的程序,函数和变量较多的情况下,这时候就需要打断点了,更容易定位问题。 一、添加断点 在代码的行标前面&…...
微服务02-docker
1、Docker架构 1.1 镜像和容器 Docker中有几个重要的概念: 镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。Docker镜像是用于创建 Docker 容器的模板 。就像面向对象编…...
CSS:盒子模型 与 多种横向布局方法
目录 盒子模型块级盒子内联级盒子内联块级盒子弹性盒子display 改变模型区域划分text 内容区padding 填充区border 边框区margin 外边距直接设置盒子大小 布局横向布局方法一 float 浮起来方法二 内联块级元素实现方法三 弹性盒子模型 盒子模型 块级盒子 独占一行,…...
用node.js搭建一个视频推流服务
由于业务中有不少视频使用的场景,今天来说说如何使用node完成一个视频推流服务。 先看看效果: 这里的播放的视频是一个多个Partial Content组合起来的,每个Partial Content大小是1M。 一,项目搭建 (1)初…...
【SpringCloud】Feign远程调用
先来看我们以前利用RestTemplate发起远程调用的代码: String url "http://userservice/user/" order.getUserId(); User user restTemplate.getForObject(url, User.class);存在下面的问题: • 代码可读性差,编程体验不统一 • …...
集合Collection-List-ArrayList学习
一、集合 集合是数据容器。相较于数组集合具有以下几个特点: 数组一旦创建,长度不可改变。集合的长度会自动扩容。集合具有很多数组没有的功能函数API数组元素的存储特点单一,不同的集合有不同的存储特点。 1. Collection顶层接口 Collect…...
mybatispuls代码生成器
引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
