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、总结

任重道远 ...

相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone4 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui