当前位置: 首页 > news >正文

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瘦身优化

随着业务迭代&#xff0c;apk体积逐渐变大。项目中积累的无用资源&#xff0c;未压缩的图片资源等&#xff0c;都为apk带来了不必要的体积 增加。而APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。在讨论如何缩减应用的大小之前&#xff0c;有必要了解下应用 APK …...

前端主题切换方案——CSS变量

前言 主题切换是前端开发中老生常谈的问题&#xff0c;本文将介绍主流的前端主题切换实现方案——CSS变量 CSS变量 简介 编写CSS样式时&#xff0c;为了避免代码冗余&#xff0c;降低维护成本&#xff0c;一些CSS预编译工具&#xff08;Sass/Less/Stylus&#xff09;等都支…...

Java8 list多属性去重

大家好&#xff0c;我是三叔&#xff0c;很高兴这期又和大家见面了&#xff0c;一个奋斗在互联网的打工人。 在 Java 开发中&#xff0c;我们经常会面临对 List 中的对象属性去重的需求。然而&#xff0c;当需要根据多个属性来进行去重时&#xff0c;情况会稍微复杂一些。本篇…...

kafka-保证数据不重复-生产者开启幂等性和事务的作用?

1. 生产者开启幂等性为什么能去重&#xff1f; 1.1 场景 适用于消息在写入到服务器日志后&#xff0c;由于网络故障&#xff0c;生产者没有及时收到服务端的ACK消息&#xff0c;生产者误以为消息没有持久化到服务端&#xff0c;导致生产者重复发送该消息&#xff0c;造成了消…...

[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 &#xff0c;你需要将这个数组分成 m 个非空的连续子数组。 设计一个算法使得这 m 个子数组各自和的最大值最小。 示例 1&#xff1a;输入&#xff1a;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&#xff1a; / -------…...

最新2024届【海康威视】内推码【GTK3B6】

最新2024届【海康威视】内推码【GTK3B6】 【内推码使用方法】 1.请学弟学妹们登录校招官网&#xff0c;选择岗位投递简历&#xff1b; 2.投递过程中填写内推码完成内推步骤&#xff0c;即可获得内推特权。 内推码&#xff1a;GTK3B6 内推码&#xff1a;GTK3B6 内推码&…...

边写代码边学习之LSTM

1. 什么是LSTM 长短期记忆网络 LSTM&#xff08;long short-term memory&#xff09;是 RNN 的一种变体&#xff0c;其核心概念在于细胞状态以及“门”结构。细胞状态相当于信息传输的路径&#xff0c;让信息能在序列连中传递下去。你可以将其看作网络的“记忆”。理论上讲&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. 串口连接开发板&#xff0c;配置nfs5 修改网络文件6 验证nfs 是否成功总结 1. 配置VM虚拟机的桥接网络 右击设置&#xff0c;选择添加网络&#xff0c;按照如下顺序操作…...

【Android】Retrofit2和RxJava2新手快速上手

写这篇博客的目的 网上关于Retrofit2和RxJava2的博客特别多&#xff0c;但是内容特别复杂&#xff0c;一上来就讲解很高级的用法 其实我们没必要像高考做题家一样&#xff0c;把每个API都背的滚瓜烂熟 熟悉基本用法&#xff0c;高阶用法需要的时候再逐个了解就行了 因为博客…...

1.4 Nacos注册中心

目录 什么是Nacos Nacos下载和安装 下载和安装 启动 Nacos服务注册与发现 Nacos的服务分级存储模型 什么是分级存储模型 配置实例集群 配置同集群优先的负载均衡 权重配置 点击编辑按钮 配置所需的权重 环境隔离 创建namespace 什么是Nacos Nacoshttps://nacos.i…...

AOJ 2200 Mr. Rito Post Office 最短路径+动态规划+谨慎+思维

我写了好多注释&#xff0c;一看就能看懂&#xff0c;这个题目我想了6&#xff0c;7个小时&#xff0c;一开始忽略了船的位置和要把船安置的位置一致的情况&#xff0c;补上就对了。 #include <iostream> using namespace std; int inf 0x3f3f3f3f, num[1007], dp[1007…...

红米电视 ADB 安装 app 报错 failed to authenticate xxx:5555

开启电视开发者模式&#xff0c;允许安装未知来源应用及开启 ADB 调试电脑端下载 adb 工具 点击下载同一局域网的电脑使用 adb 工具连接&#xff08;提前查看电视 IP&#xff09;D:\adb>adb connect 192.168.1.7 * daemon not running; starting now at tcp:5037 * daemon s…...

Linux 下设置开机自启动的方法

文章目录 事先准备对于普通的 Linux对于 RedHat Enterprise Linux 9 笔者的运行环境&#xff1a; 设置成功过的 Linux&#xff1a; RedHat Enterprise Linux 9 x86_64 CentOS 8 x86_64 事先准备 进行这个教程之前&#xff0c;必须要先安装好一个 Linux 操作系统。这个 Linux…...

MySQL常见问题处理(三)

MySQL 常见问题解决 夕阳留恋的不是黄昏&#xff0c;而是朝阳 上一章简单介绍了MySQL数据库安装(二), 如果没有看过, 请观看上一章 一. root 用户密码忘记&#xff0c;进行重置操作 复制内容来源链接: https://blog.csdn.net/weixin_48927364/article/details/123556927 一.…...

maven中常见问题

文章目录 一、配置项提示二、父子打包三、打包之后不显示target四、自定义打包之后的jar包名称五、整个项目打包5.1、父项目管理插件和微服务打包 一、配置项提示 SpringBoot中提示错误信息 表示的是SpringBoot中的注释提示没有配置&#xff01;那么可以来使用一下springboot官…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...