在 Android 中选择特定 ABI 的两种不同方式

Two different ways to choose specific ABI in Android

我正在使用 CMake 在我当前的 Android 项目中使用 JNI。为了让我的 apk 变小,我只想支持 arm64-v8a。我发现有两种方法可以做到:

(1) 在Cmake

内设置选项
defaultConfig {
    applicationId "com.example.something.here"
    minSdkVersion 23
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags "-frtti -fexceptions"
            abiFilters "arm64-v8a"
        }
    }
}

(2) 在ndk

内设置选项
defaultConfig {
    applicationId "com.example.something.here"
    minSdkVersion 23
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags "-frtti -fexceptions"
        }
    }
    ndk {
        abiFilters "arm64-v8a"
    }
}

他们都创建了可用的 APK。但我对三件事很好奇。

  1. 我只为 JNI 使用 CMake。为什么在 ndk 块内设置(选项 2)有效?
  2. apk 大小不同。选项 1 生成 15.0 MB,而选项 2 生成 12.3 MB。这是为什么?
  3. 这两个选项生成的 apk 之间是否存在任何速度或性能差异?

I am using only CMake for JNI. Why setting inside ndk block (option 2) works?

ndkexternalNativeBuild { ndkBuild 不同。

The apks are different in size. Option 1 generated 15.0 MB while option 2 generated 12.3 MB. Why is that?

  • ndk { abiFilters 指定应为哪些 ABI gradle 构建并将其打包到您的 APK 中。
  • externalNativeBuild { **** { abiFilters 仅指定 gradle 应为哪些 ABI 构建(因此,如果您出于某种原因需要,您可能会为实际上未包含在 APK 中的 ABI 构建)。

很难说为什么会有大小差异,因为我们不是坐在您的开发机器上。但一个似是而非的解释是,您的项目目录中有一些用于另一个 ABI 的现有库。然后,当您删除 ndk { abiFilters 时,您告诉 gradle 也可以将旧库打包到您的 APK 中,从而增加 APK 的大小。

Are there any speed or performance difference between the apks generated by the two options?

如果您指的是运行时速度差异,那么我明白 none。构建时间和安装时间可能会有所不同,具体取决于您构建的数量和打包到 APK 中的数量。