美文网首页Android进阶之路安卓知识总结
Android性能优化 - apk包体优化

Android性能优化 - apk包体优化

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

    1.了解apk包结构

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


      在这里插入图片描述
    • assets 包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。

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

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

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

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

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

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

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


      在这里插入图片描述
    • 在自己工程里面,反编译好了,可以直接看类。


      在这里插入图片描述
    • 已编译的资源文件也能看到。

    在这里插入图片描述

    2.具体优化

    2.1 图片优化

    • webp 替代jdp,png,用 Android Size Analyzer 插件可以帮你找到要替换的图片。
    • 使用矢量图 SVG ,矢量图无论放大缩小都没有锯齿,非常适合做图标 。
    • iconfont - 阿里矢量图图库
    SVG下载
    使用SVG
    调节参数
    • 使用 hint 可以修改颜色,这样就不需要再加入新的图片了。
    <!-- 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


      Analyze
    • 输入 Unused resource
      Analyze
    • 选择分析的范围。
    在这里插入图片描述
    • 分析结果再删除,这里建议还是一个个过,确保没地方使用再删除。


      删除资源
    • 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"
                }
            }
        }
    }
    
    • 加入上面代码后我们可以选择架构。


      arm
    • 还可以一次性打多个。
    android {
        splits {
            abi {
                enable true
                reset()
                include 'arm64-v8a','armeabi-v7a'
                universalApk true //是否打包一个包含所有so的apk
            }
        }
    
    • 打了3个,其中一个是包含所有动态库的包。


      多个包

    3. 总结

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

    相关文章

      网友评论

        本文标题:Android性能优化 - apk包体优化

        本文链接:https://www.haomeiwen.com/subject/hvwboktx.html