如何为不同的 android ABI 选择不同的 minSdkVersion?

How to choose different minSdkVersion for different android ABI?

我有 Android 构建 armeabi-v7aarm64-v8a 的应用程序。这是 build.gradle:

apply plugin: 'com.android.library'

allprojects {
    repositories {
        jcenter()
        google()
    }
}

android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        externalNativeBuild {
            cmake {
                // Linker flags and Visibility options keeps the size of the library small
                cppFlags "-std=c++11"
                arguments "-DANDROID_STL=gnustl_static",
                          "-DANDROID_CPP_FEATURES=rtti exceptions",
                          "-DANDROID_TOOLCHAIN=gcc"
            }
        }
    }

    buildTypes {
        release {
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            externalNativeBuild {
                cmake {
                    cppFlags "-Wl,--exclude-libs=ALL -Wl,--gc-sections -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections"
                }
            }
        }
        debug {
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
        }
    }
    externalNativeBuild {
        cmake {
            path 'CMakeLists.txt'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

我正在使用 minSdkVersion = 21 来支持 arm64。我想根据 abiFilters 更改 minSdkVersion 即,对 v7 使用 16,对 arm64 使用 21。

有关 minSdkVersion 属性 的工作原理,请参阅以下来自 official documentation 的引述:

  1. If there exists a platform version for the ABI equal to minSdkVersion, CMake uses that version. Otherwise,
  2. if there exists platform versions lower than minSdkVersion for the ABI, CMake uses the highest of those platform versions. This is a reasonable choice because a missing platform version typically means that there were no changes to the native platform APIs since the previous available version.
  3. Otherwise, CMake uses the next available platform version higher than minSdkVersion.

并且在回答您的另一个问题时曾提到它:

I am using the minSdkVersion = 21 to support arm64. I would like to change the minSdkVersion based on the abiFilters i.e., use 16 for v7 and use 21 for arm64.

我的理解是您正在尝试支持没有 64 位本机二进制文件的较旧(api 级别低于 21)32 位设备。我想说“productFlavor”是正确的方向。例如。您可以像下面这样配置 gradle 来实现您的期望:


android {
   ...

    flavorDimensions "api", "mode"

    productFlavors {

        minApi16 {
            dimension "api"
            minSdkVersion 16
            versionCode android.defaultConfig.versionCode
            versionNameSuffix "-minApi16"
            ndk {
                abiFilters 'armeabi-v7a'
            }
        }

        minApi21 {
            dimension "api"
            minSdkVersion 21
            versionCode android.defaultConfig.versionCode
            versionNameSuffix "-minApi21"
            ndk {
                abiFilters 'arm64-v8a'
            }
        }

    }
   ...
}

minSdkVersion 16minSdkVersion 21 将帮助您选择最合适的 NDK 版本。


编辑#1

How to choose different minSdkVersion for different android ABI?

minSdkVersion 是 属性 表示您的应用可以安装的最低 Android 版本。对于单个 APK,这是一个无条件的特征。所以:

  • 如果您想有一个 APK 来支持从 api 16 开始的所有设备,那么您必须将 minSdkVersion 设置为 16 .
  • 如果您想有一个 APK 同时支持 32 位设备和 64 位设备,您必须提供一整套 ALL 32 位和 64 位共享库。

否则,您必须提供按 ABI 拆分的不同 APK 和 minSdkVersion

您无需执行所选答案中提到的任何操作。只需设置 minSdkVersion 16,64 位 ABI 将自动使用 minSdkVersion 21,因为这是 64 位的最低可用 API。