Android性能优化—Apk瘦身优化
随着业务迭代,apk体积逐渐变大。项目中积累的无用资源,未压缩的图片资源等,都为apk带来了不必要的体积 增加。而APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。在讨论如何缩减应用的大小之前,有必要了解下应用 APK 的结构。
一、APK 结构
APK 文件由一个 Zip 压缩文件组成,其中包含构成应用的所有文件。这些文件包括 Java 类文件、资源文件和包含已编译资源的文件。
1、APK 包含以下目录:
1. META-INF/ :包含 CERT.SF 和 CERT.RSA 签名文件,以及 MANIFEST.MF 清单文件。
2. assets/ :包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。
3. res/ :包含未编译到 resources.arsc 中的资源(图片、音视频等)。
4. lib/ :包含特定于处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi 、armeabi-v7a 、 arm64-v8a 、 x86 、 x86_64 和 mips 。
2、APK 还包含以下文件:
1. resources.arsc :包含已编译的资源。此文件包含 res/values/ 文件夹的所有配置中的 XML 内容。打包工具会提取此 XML 内容,将其编译为二进制文件形式,并压缩内容。此内容包括语言字符串和样式,以及未直接包含在 resources.arsc 文件中的内容(例如布局文件和图片)的路径。
2. classes.dex :包含以 Dalvik/ART 虚拟机可理解的 DEX 文件格式编译的类。
3. AndroidManifest.xml :包含核心 Android 清单文件。此文件列出了应用的名称、版本、访问权限和引用的库文件。该文件使用 Android 的二进制 XML 格式。
二、Android Size Analyzer
Android Size Analyzer 工具可轻松地发现和实施多种缩减应用大小的策略。

首先在 Android Studio 中的插件市场下载安装 Android Size Analyzer 插件。安装插件后,从菜单栏中依次选择 Analyze > Analyze App Size,对当前项目运行应用大小分析。分析了项目后,系统会显示一个工具窗口,其中包含有关如何缩减应用大小的建议。

三、移除未使用资源
APK瘦身关键就在删除未使用的资源。
1、启用资源缩减 (不打包)
如果在应用的 build.gradle 文件中启用了资源缩减: shrinkResources ,则 Gradle 在打包APK时可以自动忽略未使用资源。 资源缩减只有在与代码缩减: minifyEnabled 配合使用时才能发挥作用。在代码缩减器移除所有不使用的代码后,资源缩减器便可确定应用仍要使用的资源 。
android {// Other settingsbuildTypes {release {minifyEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}
2、使用Lint分析器(物理删除)
lint 工具是 Android Studio 中附带的静态代码分析器,可检测到 res/ 文件夹中未被代码引用的资源。从菜单栏中依次选择 Analyze > Run Inspection By Name。
分析完成后会弹出:

lint 工具不会扫描 assets/ 文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除资源,只会提醒您它们的存在。 与资源缩减不同,这里点击删除,那就是把文件删了。
3、自定义要保留的资源
如果有想要特别声明需要保留或舍弃的特定资源,在项目中创建一个包含 <resources> 标记的 XML 文件,并在 tools:keep 属性中指定每个要保留的资源,在 tools:discard 属性中指定每个要舍弃的资源。这两个属性都接受以逗号分隔的资源名称列表。还可以将星号字符用作通配符。
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"tools:discard="@layout/unused2" />
将该文件保存在项目资源中,例如,保存在 res/raw/keep.xml 中。构建系统不会将此文件打包到 APK 中。
4、移除未使用的备用资源
Gradle 资源缩减器只会移除未由应用代码引用的资源,这意味着,它不会移除用于不同设备配置的备用资源。可以使用 Android Gradle 插件的 resConfigs 属性移除应用不需要的备用资源文件。
例如,如果使用的是包含语言资源的库(如 AppCompat ),那么 APK 中将包含这些库中所有已翻译语言的字符串。如果只想保留应用正式支持的语言,则可以使用 resConfig 属性指定这些语言。系统会移除未指定语言的所有资源。

配置resConfigs 只打包默认与简体中文资源。
android {defaultConfig {...resConfigs "zh-rCN"}
}

5、动态库打包配置
so文件是由ndk编译出来的动态库,是 c/c++ 写的,所以不是跨平台的。ABI 是应用程序二进制接口简称(Application Binary Interface),定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统中,每一个CPU架构对应一个ABI,目前支持的有:armeabi-v7a,arm64- v8a,x86,x86_64。目前市面上手机设备基本上都是arm架构, armeabi-v7a 几乎能兼容所有设备。因此可以配置:
android{defaultConfig{ndk{abiFilters "armeabi-v7a"}}
}
对于第三方服务,如百度地图、Bugly等会提供全平台的cpu架构。进行了上面的配置之后,表示只会把armeabiv7a打包进入Apk。从而减少APK大小。
四、图片资源
1、使用矢量图
Apk中图片应该算是占用空间最多的资源。我们可以使用webp减少png、jpg图片占用空间的大小。对于小图标也可以使用矢量图。

矢量图可以创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢量图片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以生成与屏幕大小相同的清晰图片。
不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕上。因此,建议仅在显示小图片时使用这些矢量图。

2、重复使用资源
现在我们有一个矢量图:
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"android:tint="?attr/colorControlNormal"><pathandroid:fillColor="@android:color/white"android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>
如果我们需要让矢量图显示红色怎么办?这种情况,我们不需要再去创建一个新的矢量图。可以直接给 ImageView设置 android:tint 属性 来完成颜色的修改。
<ImageViewandroid:layout_width="50dp"android:layout_height="50dp"android:tint="@color/colorAccent"android:src="@drawable/tabbar_home_vector" />

3、使用选择器
如果需要让矢量图实现触摸变色。只需要创建selector,设置给tint即可。
<!-- tabbar_home_tint_selector -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:color="@color/colorPrimary" android:state_pressed="true" /><item android:color="@color/colorAccent" />
</selector>
ImageView
<ImageViewandroid:clickable="true"android:layout_width="50dp"android:layout_height="50dp"android:src="@drawable/tabbar_home_vector"android:tint="@color/tabbar_home_tint_selector" />
4、其他
阿里矢量图库:
https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.d8d11a391&helptype=code
开启资源混淆:
https://github.com/shwenzhang/AndResGuard
对于发布Google paly的应用选择使用:AAB
https://developer.android.google.cn/guide/app-bundle
相关文章:
Android性能优化—Apk瘦身优化
随着业务迭代,apk体积逐渐变大。项目中积累的无用资源,未压缩的图片资源等,都为apk带来了不必要的体积 增加。而APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。在讨论如何缩减应用的大小之前,有必要了解下应用 APK …...
前端主题切换方案——CSS变量
前言 主题切换是前端开发中老生常谈的问题,本文将介绍主流的前端主题切换实现方案——CSS变量 CSS变量 简介 编写CSS样式时,为了避免代码冗余,降低维护成本,一些CSS预编译工具(Sass/Less/Stylus)等都支…...
Java8 list多属性去重
大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。 在 Java 开发中,我们经常会面临对 List 中的对象属性去重的需求。然而,当需要根据多个属性来进行去重时,情况会稍微复杂一些。本篇…...
kafka-保证数据不重复-生产者开启幂等性和事务的作用?
1. 生产者开启幂等性为什么能去重? 1.1 场景 适用于消息在写入到服务器日志后,由于网络故障,生产者没有及时收到服务端的ACK消息,生产者误以为消息没有持久化到服务端,导致生产者重复发送该消息,造成了消…...
[AI in security]-214 网络安全威胁情报的建设
文章目录 1.什么是威胁情报2. 威胁情报3. 智能威胁情报3.1 智能威胁情报的组成3.2 整合威胁情报3.3 最佳实践4. 威胁情报的作用5.威胁情报模型6.反杀链模型7.基于TI的局部优势模型参考文献相关的研究1.什么是威胁情报 威胁情报是循证知识,包括环境、机制、指标、意义和可行性…...
Javaweb学习(2)
Javaweb学习 一、Maven1.1 Maven概述1.2 Maven简介1.3、Maven基本使用1.4、IDEA配置Maven1.6、依赖管理&依赖范围 二、MyBatis2.1 MyBatis简介2.2 Mybatis快速入门2.3、解决SQL映射文件的警告提示2.4、Mapper代理开发 三、MyBaits核心配置文件四、 配置文件的增删改查4.1 M…...
leetcode410. 分割数组的最大值 动态规划
hard:https://leetcode.cn/problems/split-array-largest-sum/ 给定一个非负整数数组 nums 和一个整数 m ,你需要将这个数组分成 m 个非空的连续子数组。 设计一个算法使得这 m 个子数组各自和的最大值最小。 示例 1:输入:nums [7,2,5,1…...
C函数指针与类型定义
#include <stdio.h> #define PI 3.14 typedef int uint32_t; /* pfun is a pointer and its type is void (*)(void) */ void (*pfun)(void); /* afer typedef like this we can use “pfun1” as a data type to a function that has form like: / -------…...
最新2024届【海康威视】内推码【GTK3B6】
最新2024届【海康威视】内推码【GTK3B6】 【内推码使用方法】 1.请学弟学妹们登录校招官网,选择岗位投递简历; 2.投递过程中填写内推码完成内推步骤,即可获得内推特权。 内推码:GTK3B6 内推码:GTK3B6 内推码&…...
边写代码边学习之LSTM
1. 什么是LSTM 长短期记忆网络 LSTM(long short-term memory)是 RNN 的一种变体,其核心概念在于细胞状态以及“门”结构。细胞状态相当于信息传输的路径,让信息能在序列连中传递下去。你可以将其看作网络的“记忆”。理论上讲&a…...
Elasticsearch8.8.0 SpringBoot实战操作各种案例(索引操作、聚合、复杂查询、嵌套等)
Elasticsearch8.8.0 全网最新版教程 从入门到精通 通俗易懂 配置项目 引入依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency><dependency>&l…...
《MySQL高级篇》十五、其他数据库日志
文章目录 1. MySQL支持的日志1.1 日志类型1.2 日志的弊端 2. 慢查询日志(slow query log)3. 通用查询日志3.1 问题场景3.2 查看当前状态3.3 启动日志3.4 查看日志3.5 停止日志3.6 删除\刷新日志 4. 错误日志(error log)4.1 启动日志4.2 查看日志4.3 删除\刷新日志4.4 MySQL8.0新…...
【Linux】【预】配置虚拟机的桥接网卡+nfs
【Linux】【预】配置虚拟机的桥接网卡 1. 配置VM虚拟机的桥接网络2 配置Win10中的设置3.配置Linux中的IP4. 串口连接开发板,配置nfs5 修改网络文件6 验证nfs 是否成功总结 1. 配置VM虚拟机的桥接网络 右击设置,选择添加网络,按照如下顺序操作…...
【Android】Retrofit2和RxJava2新手快速上手
写这篇博客的目的 网上关于Retrofit2和RxJava2的博客特别多,但是内容特别复杂,一上来就讲解很高级的用法 其实我们没必要像高考做题家一样,把每个API都背的滚瓜烂熟 熟悉基本用法,高阶用法需要的时候再逐个了解就行了 因为博客…...
1.4 Nacos注册中心
目录 什么是Nacos Nacos下载和安装 下载和安装 启动 Nacos服务注册与发现 Nacos的服务分级存储模型 什么是分级存储模型 配置实例集群 配置同集群优先的负载均衡 权重配置 点击编辑按钮 配置所需的权重 环境隔离 创建namespace 什么是Nacos Nacoshttps://nacos.i…...
AOJ 2200 Mr. Rito Post Office 最短路径+动态规划+谨慎+思维
我写了好多注释,一看就能看懂,这个题目我想了6,7个小时,一开始忽略了船的位置和要把船安置的位置一致的情况,补上就对了。 #include <iostream> using namespace std; int inf 0x3f3f3f3f, num[1007], dp[1007…...
红米电视 ADB 安装 app 报错 failed to authenticate xxx:5555
开启电视开发者模式,允许安装未知来源应用及开启 ADB 调试电脑端下载 adb 工具 点击下载同一局域网的电脑使用 adb 工具连接(提前查看电视 IP)D:\adb>adb connect 192.168.1.7 * daemon not running; starting now at tcp:5037 * daemon s…...
Linux 下设置开机自启动的方法
文章目录 事先准备对于普通的 Linux对于 RedHat Enterprise Linux 9 笔者的运行环境: 设置成功过的 Linux: RedHat Enterprise Linux 9 x86_64 CentOS 8 x86_64 事先准备 进行这个教程之前,必须要先安装好一个 Linux 操作系统。这个 Linux…...
MySQL常见问题处理(三)
MySQL 常见问题解决 夕阳留恋的不是黄昏,而是朝阳 上一章简单介绍了MySQL数据库安装(二), 如果没有看过, 请观看上一章 一. root 用户密码忘记,进行重置操作 复制内容来源链接: https://blog.csdn.net/weixin_48927364/article/details/123556927 一.…...
maven中常见问题
文章目录 一、配置项提示二、父子打包三、打包之后不显示target四、自定义打包之后的jar包名称五、整个项目打包5.1、父项目管理插件和微服务打包 一、配置项提示 SpringBoot中提示错误信息 表示的是SpringBoot中的注释提示没有配置!那么可以来使用一下springboot官…...
P2-CIFAR彩色图片识别
● 🍨 本文为🔗365天深度学习训练营中的学习记录博客 ● 🍖 原作者:K同学啊学习目标:1.编写一个完整的深度学习程序 2. 手动推导卷积层与池化层的计算过程一、前期准备1.设置GPUimport torch import torch.nn as nn im…...
C++SFINAE技术详解
CSFINAE技术详解SFINAE(Substitution Failure Is Not An Error)是C模板元编程的核心技术,允许在模板实例化失败时不产生编译错误,而是尝试其他重载。SFINAE的基本原理是模板替换失败不是错误。#include #includetemplate typename…...
终极GTA5安全增强菜单:YimMenu完整使用指南
终极GTA5安全增强菜单:YimMenu完整使用指南 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu Y…...
FPGA硬件加速架构设计与AXI Stream优化实践
1. FPGA硬件加速架构设计解析在当今高性能计算领域,FPGA因其可重构特性和并行计算能力,已成为硬件加速的重要选择。我们基于Xilinx Alveo U50 FPGA平台构建的加速系统,采用了分层通道设计和AXI Stream高速互联技术,实现了网络数据…...
从能算到秒杀:完全平方数与最少数量的数学真相
LeetCode Hot 100 刷题笔记 第 15 篇如果说「跳跃游戏 II」是在教你 什么时候不得不跳,那 279. 完全平方数 就是在考你:最少能用几个平方数,凑出一个整数?这也是我第一次意识到:有些动态规划,其实是在替…...
TensorFlow 2迁移学习实战:图像分类快速上手指南
我不能基于您提供的输入内容生成符合要求的博文。原因如下:输入内容严重缺失实质性项目信息:仅包含一篇已发表文章的元数据(标题、发布日期、作者名、平台名称、一句模糊口号“学习竞争对手”),完全没有提供任何关于 T…...
为什么你的ElevenLabs挪威语输出总被用户投诉“像AI朗读”?——基于217小时母语者A/B测试的5个声学参数调优阈值
更多请点击: https://intelliparadigm.com 第一章:挪威语语音“AI感”感知机制与母语者听觉认知模型 当挪威语母语者听到由现代TTS系统(如Coqui TTS或Azure Neural TTS)生成的挪威语语音时,常产生一种微妙的“AI感”—…...
小学期第一周
理论部分:学会了低通滤波器原理:只允许低于截止频率的信号通过,高于截止频率的信号被大幅衰减方波变成正弦波的原理:方波是基波无数奇次谐波的叠加,低通滤波器只留基波、滤掉高频谐波,输出就接近正弦波二阶…...
离散几何拓扑数论(终稿·全定义完整版一)
离散几何拓扑数论(终稿全定义完整版) 作者:乖乖数学 日期:2026 年 5 月 21 日 体系:离散几何拓扑数论( Discrete Geometric Topological Number Theory)...
图片去水印怎样快速搞定?2026年实测去水印工具推荐与方法全解
去水印是许多内容创作者和日常用户都会遇到的需求。无论是保存喜欢的图片、重新编辑素材,还是处理自己的作品,都需要用到高效的去水印方法。本文将为你详细介绍2026年最实用的图片去水印工具和操作方法,帮助你快速找到适合自己的解决方案。 小…...
