欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android APK瘦身实战总结

程序员文章站 2022-07-10 18:48:22
随着APP版本的不断迭代,apk的包体积也越来越大,apk瘦身便显得很有必要。做apk瘦身不但能减少包大小,还能一定程度上加快IDE的编译打包速度。下面以我司项目为例,阐述我在做项目瘦身的过程。既然是瘦身,我们肯定要先分析下apk里哪些文件所占体积比较大,通过Android Studio 自带的Analyze Apk工具,我们可知:通过上图可知,资源文件、lib包、dex文件、resources.arsc所占比例较大,其中dex文件里压缩的主要是我们的字节码文件,可以将dex里跟debug相关的...

目录

图片优化

动态库打包优化

国际化资源配置优化

无用资源剔除

代码压缩/代码混淆

资源压缩/资源混淆

总结


随着APP版本的不断迭代,apk的包体积也越来越大,apk瘦身便显得很有必要。做apk瘦身不但能减少包大小,还能一定程度上加快IDE的编译打包速度。下面以我司项目为例,阐述我在做项目瘦身的过程。

既然是瘦身,我们肯定要先分析下apk里哪些文件所占体积比较大,通过Android Studio 自带的Analyze Apk工具,我们可知:

Android APK瘦身实战总结

通过上图可知,资源文件、lib包、dex文件、resources.arsc所占比例较大,其中dex文件里压缩的主要是我们的字节码文件,可以将dex里跟debug相关的信息剔除,以达到减小文件大小的目的,但这个对技术要求略高,没有深入去尝试。我主要通过以下几个途径去做:

  1. 图片优化
  2. 动态库打包优化
  3. 国际化资源配置优化
  4. 无用资源剔除
  5. 代码压缩/代码混淆
  6. 资源压缩/资源混淆

图片优化

优先使用VectorDrawable,SVG图片是可缩放矢量图,它不会像位图一样因为缩放而让图片质量下降,优点在与可以减少文件大小,并且只提供一套图即可,常用于简单小图标。SVG是有xml定义的,其标准根节点为<svg>,而Android只支持<vector>,我们可以通过IDE将<svg>转为<vector>。

如下在Android Studio的res文件夹上右键点击:

Android APK瘦身实战总结Android APK瘦身实战总结

如果有多个svg需要转换为android的vector,则可以通过第三方工具 svg2vector 进行批量转换,执行转换命令:

java -jar svg2vector-cli-1.0.0.jar -d . -o a -h 20 -w 20 

-d 指定svg文件所在目录

-o 输出android vector图像目录

-h 设置转换后svg的高

-w 设置转换后svg的宽

使用SVG图片的兼容性问题

在Android 5.0 之前的版本,不支持SVG,我们可以在 build.gradle 中配置如下,适用于 Gradle 插件2.0及以上版本:

android{     
    // Gradle Plugin 2.0+ 
    defaultConfig{         
        // 利用支持库中的 VectorDrawableCompat 类,可实现 2.1 版本及更高版本中支持             
        VectorDrawable {       
           vectorDrawables.useSupportLibrary = true    
        } 
   } 
    dependencies {  
         // 支持库版本需要是 23.2 或更高版本   
        compile 'com.android.support:appcompat-v7:23.2.0' 
    }

使用矢量图 必须使用 app:srcCompat 属性,而不是 android:src,如下:

Android APK瘦身实战总结

当然还可以利用Tint着色器去改变矢量图的颜色。

如果UI无法提供VectorDrawable图片,那么webp格式也是一个不错的选择,Android Studio也支持将png或者jpg格式的图片转换为webp格式:

Android APK瘦身实战总结

注:仅仅是将项目里png转为webp格式,apk大小减小了7M。

动态库打包优化

在Android系统中,每一种CPU架构对应一种ABI,主要有:arm64-v8a(最新),armeabi,armeabi-v7a,x86,x86_64,mips,mips64。现在我们只需要配置armeabi-v7a即可(像微信、qq、支付宝、淘宝也都是只配置1种)。可以参考安卓打包的时候还需要兼容armeabi吗?

android{
    defaultConfig{
        ndk{
            abiFilters "armeabi-v7a"
        }
    }
}

注:我们项目里原来配置了两个armeabi和armeabi-v7a,只保留后者,apk大小又减小了2M。

国际化资源配置优化

我们的resources.arsc文件是一个资源映射表,所有的资源和id在这里做关联对应,如下所示:

Android APK瘦身实战总结

有时候我们使用的三方库会对国际化的各种语言做支持,但我们的项目只支持某种语言,比如中文,那么可以在gradle的defaultConfig中使用resConfg来限制打包到apk中的国际化资源文件,如下:

android{
    defaultConfig{
        // 只适配英语
        resConfigs 'zh'
    }
}

注:这个配置使得apk大小减小了0.9M。

无用资源剔除

我们可以通过Android Studio提供的工具检索出项目未被使用的代码、资源。但删除的时候一定不能​​​​一键清除,因为java类有可能是通过反射来调用的,比如项目里有跟JS交互的相关java类,IDE提示未被使用,但实际有被用。还有,资源也可以动态获取来使用,比如getResources().getIdentifier("name","defType",getPackageName()),如果某个资源仅存在动态获取资源id的方式,那么这个资源也会被检测为未被使用。所以,AS提供的一键清除所有无用资源的操作一定要慎重,不建议用:

Android APK瘦身实战总结

我们可以使用Lint来剔除无用资源,操作如下:

Android APK瘦身实战总结Android APK瘦身实战总结Android APK瘦身实战总结

也可以使用Lint来检测无用代码,操作如下:

Android APK瘦身实战总结

检测过程中我们还发现依赖了一些没有用到的三方库,其中一个适配低版本表情包的库,去掉后,apk一下小了7M....

注:我之前以为只要在配置文件里加了shrinkResources和minifyEnabled,那些无用的文件和资源不会被打包到apk中,但我一通清除之后再打包,发现整个apk也能小1M多。

代码压缩/代码混淆

在主module的build.gradle里配置minifyEnabled 为true,即压缩了代码,也混淆了代码,所有我们要处理下混淆,不然会报找不到类的错误,可以使用如下:

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

注:这个操作项目很早已经做了,此次只是记录下该方式。

资源压缩/资源混淆

资源压缩一定与代码压缩协同工作,如下:

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

经过以上步骤操作后,apk的最终打包大小变为了19M,基本减小了一半:

Android APK瘦身实战总结

总结

apk瘦身不是一次性的,不忽视每一个细节,不多写一行代码,资源能重用就重用,能用系统提供的api就用系统的,并尝试用设计模式去优化代码等。优化之路路迢迢.....

本文地址:https://blog.csdn.net/qq_21924213/article/details/108862187