Android Unsatisfied Link 使用gradle experimental v0.6.0-beta6

标签 android android-ndk android-gradle-plugin

我试图创建一个简单的项目来测试 NDK,其中 jnilib 使用预构建的 .so 库,但我不断收到 UnsatisfiedLink 错误:

使用模拟器:

java.lang.UnsatisfiedLinkError: dlopen failed: library "~/AndroidStudioProjects/HelloAndroidJni/app/src/main/jni/libs/dynamic/x86/libadd.so" not found

使用实际设备:

Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1891]:  1675 could not load needed library '~/AndroidStudioProjects/HelloAndroidJni/app/src/main/jni/libs/dynamic/armeabi/libadd.so' for 'libhello-android-jni.so' (load_library[1093]: Library '~/AndroidStudioProjects/HelloAndroidJni/app/src/main/jni/libs/dynamic/armeabi/libadd.so' not found)

.so 库有一个函数“add”,可以将 2 个数字相加。我使用 NDK 独立工具链针对不同的 ABI (doc) 编译了它:

add.c
#include "add.h"

int add(int x, int y){
    return x + y;
}

我的 jni(.c 文件):

#include <jni.h>
#include "add.h"


JNIEXPORT jint JNICALL
Java_com_example_tomas_helloandroidjni_MainActivity_addNumbersJni(JNIEnv *env, jobject instance,
                                                                  jint n1, jint n2) {

    return add(n1, n2);
}

我的文件结构如下所示:

Files structure

还有我的 gradle 文件(在 experimental gradle guide 中定义):

    apply plugin: 'com.android.model.application'

model {

    repositories {
        libs(PrebuiltLibraries) {
            libadd{
                headers.srcDir "src/main/jni/prebuilts/include"
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("src/main/jni/libs/dynamic/${targetPlatform.getName()}/libadd.so")

                }
            }
        }
    }

    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"


        sources {
            main {
                jni {
                    dependencies {
                        library "libadd" linkage "shared"
                    }
                }
            }
        }

        ndk {
            moduleName = "hello-android-jni"
            debuggable = true
        }

        defaultConfig.with {
            applicationId = "com.example.tomas.helloandroidjni"
            minSdkVersion.apiLevel = 15
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }

        buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file("proguard-android.txt"))

            }
        }

        productFlavors {
            create ("x86"){
                ndk.abiFilters.add("x86")
            }

            create("arm"){
                ndk.abiFilters.add("armeabi")
            }

            create("arm7"){
                ndk.abiFilters.add("armeabi-v7a")
            }
            create ("fat"){

            }
        }

    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
}

我不确定去哪里查看,因为我一直收到此错误...也许我需要添加一个标志或其他东西?

提前感谢您的任何建议!

编辑 1.

我尝试使用静态库,它们工作正常。因此(添加静态库)我稍微更改了文件夹的结构(相应地修改了 gradle 文件)。

我正在研究两者:

  1. 实际设备:Samsung GT-I8190L Android 4.1.2,API 16 - ARMv7 处理器版本 1 (v7l)
  2. 模拟器:Nexus 4 API 23 - x86

编辑 2.

为了编译库,我使用 NDK Standalone Toolchain :

  1. 实际设备 (ARMv7):SYSROOT=$NDK/platforms/android-21/arch-armCC="$NDK/toolchains/arm-linux-androideabi -4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT"

  2. 模拟器 (x86):SYSROOT=$NDK/platforms/android-21/arch-x86CC="/Users/Tomas/Library/Android/android- ndk-r10e/toolchains/x86-4.8/prebuilt/darwin-x86_64/bin/i686-linux-android-gcc-4.8 --sysroot=$SYSROOT"

最佳答案

这可能不是这些 native 依赖项的预期工作方式,但是 (更新:这已隐式写入文档!) 即使使用插件 0.7.0,gradle 也不会将 libadd.so 复制到 APK。不过,有一个解决方法;添加到 build.gradle 附魔:

model {
    android.sources.main {
        jniLibs.source.srcDir 'src/main/jni/libs/dynamic'
    }
}

不过,我建议将 libs/dynamic 文件夹移出 jni sources 文件夹。

关于Android Unsatisfied Link 使用gradle experimental v0.6.0-beta6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36019909/

相关文章:

java - Android 中的游戏时间

android - 以角度和速度应用于 Sprite 的脉冲

java - JNI 检测到应用程序错误 : the return type of CallObjectMethodV does not match void android. media.AudioTrack.play()

java - 为android Activity 类创建头文件

android - 原因 : invalid type code: 1C for android studio gradle

android - 微调器模式下的 TimePickerDialog

android - 为什么 WebView 无法打开某些本地 URL(Android)?

android - 发现多个文件的操作系统独立路径为 'lib/x86/libusb.so'

Android Studio 在更新后显示错误(缺少翻译)

android - 设置 Gradle 以在 Android Studio 中运行 Java 可执行文件