java 如何针对不同的Android架构?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28100291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:59:42  来源:igfitidea点击:

How to target different Android architectures?

javaandroidandroid-ndkapk

提问by AggieDev

I am currently using the OpenCV (OpenCV4Android) library which does not use the NDK (there is no C or C++ code). However, there are .so files for armeabi, armeabi-v7a, mips, and x86. If I include all of these in the project, the app size is 30mb, whereas if I include only 1, the app size is only 9mb. If I try to run the app on a device that doesn't have that device's architecture's .so file included, it crashes, whereas if I have it's .so file included, it works.

我目前使用的是不使用 NDK 的 OpenCV (OpenCV4Android) 库(没有 C 或 C++ 代码)。但是,有适用于 armeabi、armeabi-v7a、mips 和 x86 的 .so 文件。如果我在项目中包含所有这些,应用程序大小为 30mb,而如果我只包含 1 个,应用程序大小仅为 9mb。如果我尝试在不包含该设备架构的 .so 文件的设备上运行该应用程序,它会崩溃,而如果我包含它的 .so 文件,则它可以工作。

Therefore, I am wanting to release multiple APKs to different device architectures to reduce the file sizes. From what I've seen, this can only be done in the Application.mk file, but my library does not have one. Is there another way to target different Android architectures?

因此,我想将多个 APK 发布到不同的设备架构以减小文件大小。据我所知,这只能在 Application.mk 文件中完成,但我的库没有。有没有另一种方法可以针对不同的 Android 架构?

回答by CommonsWare

I am currently using the OpenCV (OpenCV4Android) library which does not use the NDK (there is no C or C++ code). However, there are .so files for armeabi, armeabi-v7a, mips, and x86.

我目前使用的是不使用 NDK 的 OpenCV (OpenCV4Android) 库(没有 C 或 C++ 代码)。但是,有适用于 armeabi、armeabi-v7a、mips 和 x86 的 .so 文件。

As immibis put it, if there are .sofiles, then it is using the NDK.

正如 immibis 所说,如果有.so文件,那么它正在使用 NDK。

If I try to run the app on a device that doesn't have that device's architecture's .so file included, it crashes, whereas if I have it's .so file included, it works.

如果我尝试在不包含该设备架构的 .so 文件的设备上运行该应用程序,它会崩溃,而如果我包含它的 .so 文件,则它可以工作。

That depends upon the device. Many x86 devices have libhoudini, which can run ARM NDK binaries, albeit more slowly than they would run native x86 binaries. Similarly, an armeabi-v7device can run armeabiNDK binaries, though perhaps more slowly, particularly if floating-point processing is used.

这取决于设备。许多 x86 设备都有libhoudini,它们可以运行 ARM NDK 二进制文件,尽管比它们运行原生 x86 二进制文件要慢。类似地,armeabi-v7设备可以运行armeabiNDK 二进制文件,但可能更慢,尤其是在使用浮点处理时。

Therefore, I am wanting to release multiple APKs to different device architectures to reduce the file sizes. From what I've seen, this can only be done in the Application.mk file, but my library does not have one.

因此,我想将多个 APK 发布到不同的设备架构以减小文件大小。据我所知,这只能在 Application.mk 文件中完成,但我的库没有。

The Application.mkfile only controls what gets compiled, not what gets distributed.

Application.mk文件只控制编译的内容,而不控制分发的内容。

Is there another way to target different Android architectures?

有没有另一种方法可以针对不同的 Android 架构?

Use Gradle for Android, perhaps in conjunction with Android Studio, and the abisplit:

使用摇篮为Android,或许在与Android工作室,并结合abi分裂

android {
  ...
  splits {
    abi {
      enable true
      reset()
      include 'x86', 'armeabi-v7a', 'mips'
      universalApk true
    }
  }
}

The abiclosure in the splitsclosure:

abi在封闭splits封闭:

  • opts into having different APK files per CPU architecture

  • sets up a whitelist of the architectures that you want

  • also requests a "universal APK" that contains all of the architectures, for use with distribution channels that do not support separate APKs by architecture

  • 选择为每个 CPU 架构使用不同的 APK 文件

  • 设置您想要的架构的白名单

  • 还请求包含所有架构的“通用 APK”,用于不支持按架构单独 APK 的分发渠道

The result of your build will be separate APKs by CPU architecture, plus the universal one.

您的构建结果将是按 CPU 架构划分的单独 APK,以及通用 APK。

回答by Kiran

Each apk for the application should have unique version code specified by android:versionCode. Some x86 devices can run ARMv7 binaries. So, to avoid a case of ARMv7 apk getting downloaded/used in x86 device ( and similar scenarios for other architectures ), you should order the version codes. For e.g., order the version codes so that, the x86 APK has a higher version code than ARMv7. More on versioning at this link.

应用程序的每个 apk 都应具有由android:versionCode. 某些 x86 设备可以运行 ARMv7 二进制文件。因此,为了避免在 x86 设备中下载/使用 ARMv7 apk(以及其他架构的类似场景),您应该订购版本代码。例如,对版本代码进行排序,以便 x86 APK 具有比 ARMv7 更高的版本代码。在此链接中了解更多关于版本控制的信息。

A build.gradlesample for creating unique version coded apks for each architecture of your choice is shared by ph0b at github. Copying the same below.

build.gradleph0b 在github 上共享了一个示例,用于为您选择的每个架构创建唯一版本编码的 apk 。复制下同。

splits {
        abi {
            enable true
            reset()
            include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
            universalApk true //generate an additional APK that contains all the ABIs
        }
    }

    // map for the version code
    project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]

    android.applicationVariants.all { variant ->
        // assign different version code for each output
        variant.outputs.each { output ->
            output.versionCodeOverride =
                    project.ext.versionCodes.get(output.abiFilter, 0) * 1000000 + android.defaultConfig.versionCode
        }
    }

Suggestion: Android multiple apk support documentationsuggests to not use multiple apksif apk size is less then 50mb.

建议:Android 多 apk 支持文档建议 如果 apk 大小小于50mb,不要使用多个apk。

You should generally use multiple APKs to support different device configurations only when your APK is too large (greater than 50MB) due to the alternative resources needed for different device configurations. Using a single APK to support different configurations is always the best practice, because it makes the path for application updates simple and clear for users (and also makes your life simpler by avoiding development and publishing complexity).

由于不同的设备配置需要替代资源,您通常只在您的 APK 太大(大于 50MB)时才应该使用多个 APK 来支持不同的设备配置。使用单个 APK 来支持不同的配置始终是最佳实践,因为它使应用程序更新的路径对用户来说变得简单明了(并且还通过避免开发和发布的复杂性使您的生活更简单)。

回答by sonique

I do not recommend to use this pattern to build your Build number. ARCH - BUILD, because if one day you want to come back to one APK, you will have to increase your versionCode a lot. instead you can follow this pattern: BUILD - ARCH

我不建议使用此模式来构建您的内部版本号。ARCH - BUILD,因为如果有一天你想回到一个 APK,你将不得不大量增加你的 versionCode。相反,您可以遵循此模式:BUILD - ARCH

android.defaultConfig.versionCode * 100 + project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0)

exemple for build 74 the build number will be: 7402 - armeabi-v7a 7408 - x86

例如,内部版本 74 内部版本号为:7402 - armeabi-v7a 7408 - x86