美文网首页
优化ApK大小之ABI Filters 和 APK split

优化ApK大小之ABI Filters 和 APK split

作者: gooddaytoyou | 来源:发表于2019-02-24 16:50 被阅读0次

    Demo例子代码:https://github.com/sayhellotogithub/AbifiltersAndSplit

    Android支持多种CPU处理器架构:

    • mips
    • mips64
    • armeabi
    • armeabi-v7a
    • arm64-v8a
    • x86
    • x86_64

    想要在项目中使用 native 类库,我们必须对要支持的处理机框架提供对应编译包。每个处理器架构需要我们提供一个或多个包含native代码的.so文件。

    当我们决定支持处理器架构的时候,相应的APK会疯狂的增大。对于用户来说设备架构只需要一个子集,但当用户下载APK时,会全部下载(对用户来说相当的不好)。

    通过Android Studio 查看APK文件,可以发现lib文件夹占用APK空间比较大:


    lib文件夹

    进一步看下lib文件夹下的文件,可以清楚的看到不同处理器架构文件的native库的大小:


    native so库

    当前 Google Play Store 上传APK限制是100MB。而我们的native库占用APK应用一半以上的空间。为了减少APK的大小,我们需要限制支持的处理器架构。
    在这里我介绍两种技术:

    • ABI Filters
    • APK Split

    ABI Filters

    ABI (Application Binary Interface)是两个程序模块之间的接口; 通常,其中一个是库文件或者是操作系统

    ABI filters 可以让我们包含进APK里处理器架构native文件。
    在defaultConfig中加入如下配制:

            ndk {
                abiFilters "arm64-v8a", "armeabi-v7a"
            }
    

    通过指定处理器的架构,我们可以看到我们的包小了很多:


    abiFilters "arm64-v8a", "armeabi-v7a"

    通过abiFilters配制有利有弊,在这里以用户角度与开发者角角来分析下。

    • 用户角度:APK包含了用户用不到的类库,造成APK变大,用户需要花更多的网络流量及下载的等待时间;

    • 开发者角度:这种方案提供了单一的APK,节省开发者的维护成本。

    如果我们考虑到包大小超过100M或者用户角度的话,ABI filters不再是一个可选方案。我们需要确保用户下载的只有用户需要的native库。这时我们需要使用APK split 技术。

    APK split

    APK split 允许我们自动生成多个APK文件。我们可以通过屏幕密度(mdpi, hdpi, xhdpi…)或者处理器架构(arm64-v8a, armeabi-v7a…)来进行拆分。
    通过处理架构配制:

     splits{
            // Configures multiple APKs based on ABI.
            abi {
                // Enables building multiple APKs per ABI.
                enable true
    
                // By default all ABIs are included, so use reset() and include to specify that we only
                // want APKs for x86, armeabi-v7a, and mips.
                reset()
    
                // Specifies a list of ABIs that Gradle should create APKs for.
                include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
    
                // Specifies that we want to also generate a universal APK that includes all ABIs.
                universalApk true
            }
        }
    

    生成Debug包:


    APK split

    但是由于Debug包拆分不是必须的,我们可以配制仅对release包用效。

    splits {
            abi {
                def isReleaseBuild = false
    
                gradle.startParameter.taskNames.find {
                    // Enable split for release builds in different build flavors
                    // (assemblePaidRelease, assembleFreeRelease, etc.).
                    if (it ==~ /:app:assemble.*Release/) {
                        isReleaseBuild = true
                        return true // break
                    }
    
                    return false // continue
                }
    
                // Enables building multiple APKs per ABI.
                enable isReleaseBuild
                universalApk true
            }
        }
    

    运行项目之后:


    Release

    Version codes

    由于应用商店不允许上传具有相同的VersionCode的多个APK包。我们需要对每个Release包生成对应的VersionCode。

      // Map for the version code that gives each ABI a value.
        def abiCodes = ['armeabi-v7a':1, 'arm64-v8a':2,'x86':3, 'x86_64':4]
    
        // APKs for the same app that all have the same version information.
        android.applicationVariants.all { variant ->
            // Assigns a different version code for each output APK.
            variant.outputs.each {
                output ->
                    def abiName = output.getFilter(com.android.build.OutputFile.ABI)
                    output.versionCodeOverride = abiCodes.get(abiName, 0) * 100000 + variant.versionCode
            }
        }
    
    

    我们通过Android Studio 查看app-arm64-v8a-release APK文件,发现versionCode变成了20001:


    app-arm64-v8a-release

    需要支持的处理器架构

    由于处理器架构为armeabi-v7a、arm64-v8a占市场的99%以上的份额,因此我们必须要支持。

    这里有一份Android 处理器架构的汇总建议:

    • mips (已弃用)
    • mips64 (已弃用)
    • armeabi (已弃用)
    • armeabi-v7a (需要支持— 现在最流行的处理器架构)
    • arm64-v8a (需要支持 — armeabi-v7a的新版本)
    • x86 (可选, 设备非常有限,可以用于模拟器debugging)
    • x86_64 (可选, 设备非常有限,可以用于模拟器debugging)

    相关的参考

    https://developer.android.com/google/play/publishing/multiple-apks.html#HowItWorks

    https://medium.com/androiddevelopers/smallerapk-part-4-multi-apk-through-abi-and-density-splits-477083989006

    https://proandroiddev.com/reducing-apk-size-by-using-abi-filters-and-apk-split-74a68a885f4e

    相关文章

      网友评论

          本文标题:优化ApK大小之ABI Filters 和 APK split

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