【问题标题】:Add .so (prebuilt) library from another directory to APK将另一个目录中的 .so(预构建)库添加到 APK
【发布时间】:2018-06-06 06:51:24
【问题描述】:

我正在尝试从另一个目录中包含我的 .so 库。编译我的项目工作正常。但是当我运行它时,它给了我

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.company.gimikapp-2/base.apk"],nativeLibraryDirectories=[/data/app/com. company.gimikapp-2/lib/arm, /v​​endor/lib, /system/lib]]] 找不到“libtheprebuiltlib.so”

我在 SO 中看到的常见解决方案是这样的:

sourceSets {
    main {
        jniLibs.srcDirs = ['src/main/jniLibs']
    }
}

都试过了

jniLibs.srcDirs = ['C:\\svn\\sys_libs']

jniLibs.srcDirs = ['C:/svn/sys_libs']

您实际上如何将它指向您的 Android 项目之外的另一个目录?

这是我的 CMakeList.txt:

cmake_minimum_required(VERSION 3.4.1)
add_library( native-lib
            SHARED
            src/main/cpp/source/native-lib.cpp )
add_library(theprebuiltlib SHARED IMPORTED)
set_target_properties(theprebuiltlib PROPERTIES IMPORTED_LOCATION
            C:/svn/sys_libs/libtheprebuiltlib.so)
target_include_directories(
            native-lib PRIVATE
            src/main/cpp/source/
            C:/svn/sys_includes/)
find_library( log-lib
            log)
target_link_libraries( native-lib
            theprebuiltlib
            ${log-lib})

这是我的 JNI 的 gradle 设置:

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }
            ndk {
                abiFilters 'armeabi'
            }
        }
        ...
    }
    ...
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['C:/svn/sys_libs']
        }
    }
}

【问题讨论】:

  • 检查这个解决方案medium.com/mobiwise-blog/…
  • medium.com 链接讨论了 .so 在 android 项目中时的解决方案。我的在项目之外,特别是在 C:/svn/sys_libs/
  • 让我们尝试从 build.gradle 中删除 jniLibs 设置,并检查 APK 的变化情况。顺便说一句,您启动 cmake 的部分可能不正确,也请在此处发布。
  • 已添加。希望它可以帮助你帮助我。 :)

标签: android android-ndk


【解决方案1】:

显然,您已安装 NDK r17 和 Android 插件 v.3.1.0 或更高版本(我们在 build.gradle 的已发布片段中没有看到这一点)。

但是您将 abiFilters 设置为 armeabi,它已被删除。您应该将其设置为armeabi-v7a,并确保libtheprebuiltlib.so 也是为此ABI 构建的,或者您可以download an older version of NDK 并在build.gradle 中设置依赖项

classpath 'com.android.tools.build:gradle:3.0.1'

如果你明确设置,你可以强制使用最新的插件句柄armeabi

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi'
        }
    }
}

(在你的脚本中,它在android.defaultConfig.externalNativeBuild.ndk下,所以没有效果)。

你的 build.gradle 中有一个错误,它应该是

android {
  sourceSets {
     main { 
       jniLibs.srcDir 'C:/svn/sys_libs' 
     }
   }
}

当您拥有文件C:\svn\sys_libs\armeabi\libtheprebuiltlib.so 时。但这并不能解释为什么 cmake 不能按预期工作。

【讨论】:

  • 感谢您的持续支持。我正在使用 NDK r16,但使用的是最新的 gradle。 (虽然这个答案可能对其他人有帮助,但给你 +1。)
  • 这似乎不起作用。我尝试了 gradle 3.0.1,ndk r16,并将 abiFilters 移至 android.defaultConfig.ndk。我确定我的 .so 文件适用于 armeabi
  • 好的,让我们退后一步。注释掉 externalNativeBuild 块,并查看预构建的库是否被打包(如 jniLibs 所指出的那样)。
  • 删除了所有 externalNativeBuild 块。设置 android.sourceSets.main.jniLibs.srcDirs = ['C:/svn/sys_libs'],.so 仍然丢失。
  • 相对路径怎么样?
【解决方案2】:

对于 NDK r16 和 Gradle 插件 v3.1.2,这里是分步解决方案(感谢@Alex Cohn)。

  1. 设置android.sourceSets.main.jniLibs.srcDir指向外部.so的位置

    android {
        sourceSets {
            main { 
                jniLibs.srcDir 'C:/svn/sys_libs' 
            }
       }
    }
    
  2. 确保您的外部 .so 位于上述路径(步骤 1)中,并附加了正确的架构。就我而言,它是armeabi,因此我的 .so 位于

    C:/svn/sys_libs/armeabi/libtheprebuiltlib.so
    
  3. 像这样将 ndkandroid.defaultConfig.externalNativeBuild.ndk 移动到 android.defaultConfig.ndk

    android {
        defaultConfig {
            ndk {
                abiFilters 'armeabi'
            }
        }
    }
    
  4. 确保 CMakeLists.txt 指向具有正确架构的完整路径。

    set_target_properties(theprebuiltlib PROPERTIES IMPORTED_LOCATION
            C:/svn/sys_libs/armeabi/libtheprebuiltlib.so)
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多