Android如何减少apk大小(瘦身)

本文详细介绍了如何优化Android APK的大小,包括使用AndroidSizeAnalyzer分析应用大小、移除未使用资源、启用资源缩减、使用Lint工具、自定义保留资源、删除无用资源、管理备用资源、配置动态库打包、使用矢量图、重复利用资源以及其他优化策略。通过这些方法,可以显著减小APK体积,提高应用性能。
摘要由CSDN通过智能技术生成

转载:Android如何减少apk大小
Android Apk瘦身优化

一、APK结构

  APK文件由一个Zip压缩文件组成,其中包含构成应用的所有文件。这些文件包含Java类文件、资源文件和包含已编译资源的文件。

APK包含以下目录:

  • META-INF/:包含 CERT.SFCERT.RSA 签名文件,以及MANIFEST.MF 清单文件。
  • assets/:包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。
  • res/:包含未编译到 resources.arsc 中的资源(图片、音视频等)。
  • lib/:包含特定于处理器软件层的已编译代码。此目录包含某种平台类型的子目录,如 armeabi、armeabi-v7a、arm64-v8a、x86、x86_64mips

APK还包含以下文件。在这些文件中,只有AndroidManifest.xml是必需的

  • resources.arsc:包含已编译的资源。此文件包含 res/values/ 文件夹的所有配置中的XML内容。打包工具会提取此XML内容,将其编译为二进制文件形式,并压缩内容。此内容包含语言字符串和样式,以及未直接包含在resources.arsc文件中的内容(例如布局文件和图片)的路径。
  • classes.dex:包含以 Dalvik/ART 虚拟机可理解的DEX文件格式编译的类。
  • AndroidManifest.xml:包含核心Android 清单文件。此文件列出了应用的名称、版本、访问权限和引用的库文件。此文件使用Android的二进制XML格式。

二、Android Size Analyzer

  Android Size Analyzer 工具可轻松地发现和实施多种缩减应用大小的策略。

参考: 使用 Android Size Analyzer缩减应用大小
Android Size Analyzer 安装流程:
依次选择 File > Settings(或在 Mac 上,依次选择 Android Studio > Preferences)。
1)选择左侧面板中的 Plugins 部分。
2)点击 Marketplace 标签。
3)搜索“Android Size Analyzer”插件。
4)点击分析器插件的 Install 按钮。

在这里插入图片描述

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

三、移除未使用资源

APK瘦身关键就在一个字:删,没用的就删了

四、启用资源缩减(不打包)

  如果在应用的 build.gradle 文件中启用了资源缩减:shrinkResources,则Gradle在打包APK时可以自动忽略未使用资源。资源缩减只有在与代码缩减:minifyEnabled 配合使用时才能发挥作用。在代码缩减器移除所有不使用的代码后,资源缩减器便可确定应用仍药使用的资源。

android {
	buildTypes {
		release {
			minifyEnabled true
			shrikResources true
			proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
		}
	}
}

五、使用Lint分析器(物理删除)

参考:Android Studio Lint 工具看完这一篇还不够
  lint工具是 Android Studio 中附带的静态代码分析器,可检测到 res/ 文件夹中未被代码引用的资源。从菜单栏中依次选择 Analyze > Run Inspection By Name
在这里插入图片描述
分析完成会弹出:
在这里插入图片描述

lint工具不会扫描assets/文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它不会移除资源,只会提醒您它们的存在。与资源缩减不同,这里点击删除,那就是把文件都删了。
反射引用资源:getResources().getIdentifier(“layout_main”, “layout”, getPackageName());

六、自定义要保留的资源

  如果有要想特别声明需要保留或舍弃的特定资源,在项目中创建一个包含 标记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中。

七、一键删除无用资源

  Android Studio给我们提供了一键移除所有无用的资源。从菜单栏中依次选择 Refactor > Remove Unused Resources,但是这种方式不建议使用,因为如果某资源仅存在动态获取资源id的方式,那么这个资源会被认为没用使用过,从而会直接被删除。

八、移除未使用的备用资源

   Gradle资源缩减器只会移除未由应用代码引用的资源,这意味着,它不会移除用于不同设备配置的备用资源。可以使用 Android Gradle插件的 resConfigs 属性移除应用不需要的备用资源文件。
   例如,如果使用的是包含语言资源的库(如AppCompat),那么APK中将包含这些库中所有已翻译语言的字符串。如果只想保留应用正式支持的语言,则可以使用 resConfig 属性指定这些语言。系统会移除未指定语言的所有资源。
在这里插入图片描述

android {
	defaultConfig {
		...
		resConfigs "zh-rCN"
	}
}

配置resConfigs 只打包默认与简体中文资源

在这里插入图片描述

九、动态库打包配置

   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架构。进行了上面的配置之后,表示只会把armeabi-v7a打包进入Apk。从而减少APK大小。
   对于arm64架构的设备,如果使用armeabi-v7a也能够兼容,但是不如使用arm64的so性能。因此现在部分应用市场会根据设备提供不同架构的Apk安装。此时我们需要打包出针对arm64的apk与armeabi-v7a的apk,可以使用 productFlavor

flavorDimensions "default"
productFlavors {
	arm32 {
		dimension "default"
		ndk {
			abiFilters "armeabi-v7a"
		}
	}
	arm64 {
		dimension "default"
		ndk {
			abiFilters "arm64-v8a"
		}
	}
}

也可以使用:

splits {
	abi {
		enable true
		reset()
		include 'arm64-v8a','armeabi-v7a'
		// exclude 'armeabi'
		universalApk true  // 是否打包一个包含所有so的apk
	}
}

十、使用矢量图

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

新工程默认Icon就是矢量图。

File > New > Vector Asset

在这里插入图片描述

十一、重复使用资源

现在我们有一个矢量图:

<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">
	<path
		android:fillColor="@android:color/white"
		android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>

它的显示效果为:
在这里插入图片描述
  如果我们需要让矢量图显示红色怎么办?这种情况,我们不需要再去创建一个新的矢量图。可以直接给ImageView设置 android:tint 属性来完成颜色的修改。

<ImageView
	android:layout_width="50dp"
	android:layout_height="50dp"
	android:tint="@color/colrAccent"
	android:src="@drawable/tabbar_home_vector" />
	

在这里插入图片描述
选择器

如果需要让矢量图实例触摸变色。只需要创建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
	android:clickable="true"
	android:layout_width="50dp"
	android:layout_height="50dp"
	android:src="@drawable/tabbar_home_vector"
	android:tint="@color/tabbar_home_tint_selector" />

阿里矢量图库

十二、其他

  • 使用精简版本的依赖:如protobuf-lite版本;对于分模块的库按需引入:如netty分模块引入;
  • 主动移除无用代码(开启R8/Proguard自动移除)
  • 避免使用枚举,使用@IntDef代替。
  • 开启资源混淆:https://github.com/shwenzhang/AndResGuard
  • 支付宝删除Dex debugItem:https://juejin.cn/post/6844903712201277448

对于发布Google play的应用选择使用:AAB
https://developer.android.google.cn/guide/app-bundle?hl=zh-cn

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值