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=""代替

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/img_fallback"
    android:tint="@color/color_000000_FFFFFF"/>

2.1.2 开启混淆

buildTypes {
    release {
        minifyEnabled true
        proguardFiles 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、总结

任重道远 ...

相关推荐
Dnelic-3 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen5 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年12 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿15 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神16 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛16 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法17 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter18 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快19 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl19 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5