【问题标题】:Android: including ndk .so libraries for different architectures, app crashesAndroid:包括针对不同架构、应用程序崩溃的 ndk .so 库
【发布时间】:2016-12-21 18:52:35
【问题描述】:

我对 Android 开发并不陌生,但在谈到 NDK 和 .so 库时,我完全是个新手。

我正在构建的应用程序使用第三方 SDK,它们提供了一些 .so 文件。他们为我提供了每个架构的 .so 文件(到目前为止:arm64-v8a、armeabi、armeabi-v7a、mips、mips64、x86、x86_64)。

我需要包含一个新的第三方 SDK,但他们只为 armeabi-v7a 和 x86 提供 .so 文件。 当我尝试运行我的应用程序时,它崩溃了,并且我从 SDK 中收到一个错误(我在 logcat 上看到它)指出:

SDKNAME 目前只为 armeabi-v7ax86 架构提供预建库

这是常见的情况吗?有没有办法解决这种情况?

提前非常感谢

【问题讨论】:

  • 据我了解,您只能为 armeabi-v7a 或 x86 架构构建项目。请检查您使用的是哪个构建变体,很可能不是其中任何一个。
  • 我没有在我的构建配置中使用任何指定架构的东西。再说一次,我是一个超级 n00b。我发现了这个:developer.android.com/studio/build/configure-apk-splits.html 你认为它有帮助吗?
  • 您应该提供更多信息,例如:使用Android Studio或Eclipse,配置文件...
  • 我使用的是 Android Studio (2.2.3),配置文件没什么特别的。我尝试了一个空白项目并且发生了同样的情况(当我包含这两个 SDK 时)
  • 如果您的设备是 arm64,您应该从 APK 中删除所有 64 位库,直到您获得所有这些库的 64 位版本。如果设备具有 MIPS CPU,那么您的新依赖项就不走运了,因为 ARM 仿真不够好。最后,即使在“常规”arm-v7a 平台上,第三方库之间也可能存在工具链不兼容问题。

标签: android android-ndk libraries


【解决方案1】:

您需要为您的应用程序将支持的所有架构提供所有库。

安装 APK 后,安装程序会扫描 APK 以了解其支持的架构。如果 APK 不包含本机代码,则它支持所有架构。但是,如果它确实包含本机代码,则它仅支持 APK 中包含的那些架构。大多数现代设备支持不止一种架构;例如,设备可能支持arm64-v8aarmeabi-v7a,或x86_64x86,或x86armeabi-v7a(通过仿真)。在安装时,它会查看包含哪些架构,从中选择最喜欢的架构,然后安装该架构中的所有库,而忽略其余的。 (旧的 Android 版本可能无意中在上述情况下表现出稍有不同的不一致行为 - 请参阅 https://stackoverflow.com/a/25648943/3115956。)

现在,如果您包含的其中一个库包含在所有可用架构的构建中,而另一个仅支持少数几个,则安装程序可能会选择例如arm64-v8a,因此无法获得所有必要的库。

因此,您只能支持所有库提供的架构的交集。

要实现这一点,您可以手动从提供更多架构的 SDK 中删除多余的目录,或者如果使用 Gradle 构建您的 APK,您可以将其添加到 NDK 块中:

abiFilters 'armeabi-v7a', 'x86'

【讨论】:

    【解决方案2】:

    将已编译的库存储在 app/src/main/jniLibs/{arch} 中,例如:armeabi/armeabi-v7a,然后将帖子末尾的行添加到您的应用程序 build.gradle。

    productFlavours 用于配置编译变体,因此您可以正确链接已编译的库。

    android.ndk {
            moduleName = "your_library_jni"
            cppFlags.add("-fexceptions")
            cppFlags.add("-std=c++11")
            cppFlags.add("-I" + file("src/main/jni").absolutePath)
            }
    
    android.productFlavors {
            create("x86") {
                ndk.with{
                    abiFilters.add("armeabi")
    
                    File curDir = file('./')
                    curDir = file(curDir.absolutePath)
                    String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/"
    
                    ldLibs.add(libsDir + "libyour_module.so")
    
                }
            }
            create("arm-v7a") {
                ndk.with {
                    abiFilters.add("armeabi-v7a")
    
                    File curDir = file('./')
                    curDir = file(curDir.absolutePath)
                    String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi-v7a/"
    
                    ldLibs.add(libsDir + "libyour_module.so")
    
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 2012-06-07
      相关资源
      最近更新 更多