Android:apk瘦身

本文主要记录开发中apk瘦身用到的技术,apk中最占地方的是图片、so库。图片删除一定要慎重,尤其是反射调用的,编译没问题运行反而可能崩溃!

了解 APK 结构

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

APK 包含以下目录:
  • META-INF/ :包含 CERT.SF 和 CERT.RSA 签名文件,以及 MANIFEST.MF 清单文件。
  • assets/ :包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。
  • res/ :包含未编译到 resources.arsc 中的资源(图片、音视频等)。
  • lib/ :包含特定于处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi 、 armeabi-v7a 、 arm64-v8a 、 x86 、 x86_64 和 mips 。
APK 还包含以下文件:
  • resources.arsc :包含已编译的资源。此文件包含 res/values/ 文件夹的所有配置中的 XML 内容。打包工 具会提取此 XML 内容,将其编译为二进制文件形式,并压缩内容。此内容包括语言字符串和样式,以及未直 接包含在 resources.arsc 文件中的内容(例如布局文件和图片)的路径。
  • classes.dex :包含以 Dalvik/ART 虚拟机可理解的 DEX 文件格式编译的类。
  • AndroidManifest.xml :包含核心 Android 清单文件。此文件列出了应用的名称、版本、访问权限和引用的 库文件。该文件使用 Android 的二进制 XML 格式。
1. Gradle 启用资源缩减(需用keep文件)

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

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

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

然而Gradle不能识别反射的文件,也会自动忽略,需要我们做下保存!
如果有想要特别声明需要保留或舍弃的特定资源,在项目中创建一个包含 标记的 XML 文件,并在 tools:keep 属性中指定每个要保留的资源,在 tools:discard 属性中指定每个要舍弃的资源。这两个属性都 接受以逗号分隔的资源名称列表。还可以将星号字符用作通配符。
将该文件保存在项目资源中,例如,保存在 res/raw/keep.xml 中。构建系统不会将此文件打包到 APK 中

 <?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" />
2. Lint 分析器(反射文件无法识别,可能误删)

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

  1. Analyze --> Run Inspection by name…
    在这里插入图片描述
  2. 在弹出的窗口输入unused resources后,回车
    在这里插入图片描述
  3. 根据情况,选择情况,选择整个项目、指定Module…,也可以自己过滤。点击ok
    在这里插入图片描述
  4. 得到结果,里面全是没用的文件。可以一个个删,也可以一次性删除
    在这里插入图片描述
此方法和上面一样对于反射调用的文件不能识别,可能会误删文件!慎重!慎用!
3. 动态库打包配置

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"
		} 
	}
}
4. 移除未使用的备用资源

Gradle 资源缩减器只会移除未由应用代码引用的资源,这意味着,它不会移除用于不同设备配置的备用资源。可以使用 Android Gradle 插件的 resConfigs 属性移除应用不需要的备用资源文件。

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

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

5. 使用矢量图

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

在这里插入图片描述
在这里插入图片描述

借用android:tint 属性 ,重复使用资源
<ImageView
	android:layout_width="50dp"
	android:layout_height="50dp"
	android:tint="@color/colorAccent"
	android:src="@drawable/tabbar_home_vector" />

@drawable/tabbar_home_vector

<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>

阿里矢量图库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值