Android性能优化 - apk包体优化

Posted 进击的包籽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android性能优化 - apk包体优化相关的知识,希望对你有一定的参考价值。

文章目录

  • 随着APP迭代,业务逻辑增加修改,没用的资源可能越来越多,导致包体越来越臃肿,消耗更多的手机资源。 应用的包体大小影响会很多,比如客户看了就不想安装,比如发包上传时等待时间久。
  • 因此我们有必要学习怎么清除无用资源,不影响使用的情况下尽可能压缩资源。

1.了解apk包结构

  • 我们以微信的apk包为例,看看有什么东西。

  • assets 包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。

  • lib 包含特定于处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi 、armeabi-v7a 、 arm64-v8a 、 x86 、 x86_64 和 mips。微信的只有arm64-v8a,那是因为目前android机子大部分都是arm架构,没必要放什么x86。

  • META-INF 包含 CERT.SF 和 CERT.RSA 签名文件,以及 MANIFEST.MF 清单文件。

  • res 包含未编译到 resources.arsc 中的资源(图片、音视频等),微信这里是r。

  • AndroidManifest.xml 这里的Manifest打开是二进制文件,包含核心 Android 清单文件。此文件列出了应用的名称、版本、访问权限和引用的库文件。


  • .dex文件非常多,包含以 Dalvik/ART 虚拟机可理解的 DEX 文件格式编译的类。Android的虚拟机就是用dex文件。

  • resources.arsc 包含已编译的资源。此文件包含 res/values/ 文件夹的所有配置中的 XML 内容。打包工具会提取此 XML 内容,将其编译为二进制文件形式,并压缩内容。此内容包括语言字符串和样式,以及未直包含在 resources.arsc 文件中的内容(例如布局文件和图片)的路径。

  • 以我自己项目apk为例,也可以分析各个资源占用包体大小的情况。

  • 在自己工程里面,反编译好了,可以直接看类。

  • 已编译的资源文件也能看到。

2.具体优化

2.1 图片优化

  • webp 替代jdp,png,用 Android Size Analyzer 插件可以帮你找到要替换的图片。
  • 使用矢量图 SVG ,矢量图无论放大缩小都没有锯齿,非常适合做图标 。
  • iconfont - 阿里矢量图图库



  • 使用 tint 可以修改颜色,这样就不需要再加入新的图片了。
<!-- android:tint  可以修改颜色 -->
<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/ic_home"
    android:tint="#2196F3"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
  • 如果是点击变颜色,配置select就行。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#2196F3" android:state_pressed="true"/>
    <item android:color="#E91E63" android:state_pressed="false"/>
</selector>

<!-- android:tint  可以修改颜色 -->
<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/ic_home"
    android:tint="@color/click_color"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

2.2 Android Size Analyzer插件

2.3 开启压缩

Google官方推荐 使用 R8 压缩您的应用

  • 如果在应用的 build.gradle 文件中启用了资源缩减: shrinkResources ,则 Gradle 在打包APK时可以自动忽略使用资源。 资源缩减只有在与代码缩减: minifyEnabled 配合使用时才能发挥作用。在代码缩减器移除所有不使用的代码后,资源缩减器便可确定应用仍要使用的资源 。
android 
      buildTypes 
        release 
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        
        debug
        
    

  • 可以配置keep.xml 保留资源。 还可以将星号字符用作通配符。
<?xml version="1.0" encoding="utf-8"?>
<!-- keep:保留的资源,无论是否使用 -->
<!-- discard:要舍弃掉的资源 -->
<resources
    xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/BaoActivity.xml,@drawable/bao_*.jpg"
    tools:discard="@layout/TestActivity.xml" />

2.4 使用Lint分析器

  • Analyze -> Run Inspection by Name
  • 输入 Unused resource
  • 选择分析的范围。

  • 分析结果再删除,这里建议还是一个个过,确保没地方使用再删除。

  • lint 工具不会扫描 assets/ 文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除资源,只会提醒您它们的存在。

  • xml使用的 assets 资源

   <com.airbnb.lottie.LottieAnimationView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:src="@drawable/playerdetail_detail_like_nor"
                    app:lottie_imageAssetsFolder="images"
                    app:lottie_scale="0.5" />
  • 反射引用资源:
getResources().getIdentifier("layout_main","layout",getPackageName());

2.5 使用指定语言

  • 其他语言可能有备用资源,加入配置,删除不需要的语言,一般国际化APP会重新开个工程,而不是替换语言那么简单。
android 
    defaultConfig 
        resConfigs "zh-rCN"
    

  • 开启后可以打包对比效果。

2.6 动态库打包配置

  • so文件是由ndk编译出来的动态库,是 c/c++ 写的,所以不是跨平台的。ABI 是应用程序二进制接口简称(Application Binary Interface),定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的令集,内存对齐到可用的系统函数库。在Android 系统中,每一个CPU架构对应一个ABI,目前支持的有:armeabi-v7a,arm64- v8a,x86,x86_64。目前市面上手机设备基本上都是arm架构, armeabi-v7a 几乎能兼容所有设备,arm64-v8a 是比较新的手机使用,性能更好。
  • app的build.gradle 配置一下,像微信的包就只留了arm64-v8a
android 
    defaultConfig 
         ndk
            abiFilters "arm64-v8a"
        
    

  • 比如我们接入地图或其他的SDK,他们里面自带比较全的动态库,就可以像上面这样配置,保留 armeabi-v7a 也是能基本满足,我们也可以打几种包,上架应用市场时,应用市场会根据手机下载合适的包。

  • app的build.gradle 配置一下,我们可以选arm32,arm64。

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

  • 加入上面代码后我们可以选择架构。
  • 还可以一次性打多个。
android 
	splits 
        abi 
            enable true
            reset()
            include 'arm64-v8a','armeabi-v7a'
            universalApk true //是否打包一个包含所有so的apk
        
    
  • 打了3个,其中一个是包含所有动态库的包。

3. 总结

  • 包体优化以后还有其他内容,学习了就更新,我个人是建议一段时间整理一下工程,这样找资源也方便;跟生活一样,除了定时整理,平时良好的习惯也能让你更舒服。

以上是关于Android性能优化 - apk包体优化的主要内容,如果未能解决你的问题,请参考以下文章

Android apk包体瘦身

Android apk包体瘦身

Android apk包体瘦身

Unity纹理优化:缩小包体

Android 性能优化--apk瘦身优化

Android 性能优化--apk瘦身优化