java.lang.UnsatisfiedLinkError - NDK в студийной программе для Android?

Структура папок

 app 
---main
    ---java
    ----jni
          -----Android.mk
          -----Application.mk
          ----- hello-jni.c
    ---res

в build.gradle

apply plugin: 'com.android.application'

android {
compileSdkVersion 21
buildToolsVersion "22.0.1"

defaultConfig {
    applicationId "com.example.hellojni"
    minSdkVersion 17
    targetSdkVersion 21
    sourceSets.main {
        jni.srcDirs = []
        jniLibs.srcDir 'src/main/libs'

    }

    ndk {
        moduleName "hello-jni"
        cFlags "-std=c++11 -fexceptions"
        ldLibs "log"
        stl "gnustl_shared"
        abiFilter "armeabi-v7a"
    }

    task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') {
        destinationDir file("$buildDir/native-libs")
        baseName 'native-libs'
        extension 'jar'
        from fileTree(dir: 'libs', include: '**/*.so')
        into 'lib/'
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn(nativeLibsToJar)
    }







    testApplicationId "com.example.hellojni.tests"
    testInstrumentationRunner "android.test.InstrumentationTestRunner"
}


buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
    }
}

dependencies {
    compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
}


}

в Android.mk

 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)

в hello-jni.c

include<com.example.hellojni.HelloJni.h>

#include <string.h>
 #include <jni.h>



 jstring
 Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                              jobject thiz )
{
  #if defined(__arm__)
    #if defined(__ARM_ARCH_7A__)
      #if defined(__ARM_NEON__)
        #if defined(__ARM_PCS_VFP)
          #define ABI "armeabi-v7a/NEON (hard-float)"
        #else
          #define ABI "armeabi-v7a/NEON"
        #endif
          #else
           #if defined(__ARM_PCS_VFP)
        #define ABI "armeabi-v7a (hard-float)"
         #else
        #define ABI "armeabi-v7a"
       #endif
     #endif
   #else
   #define ABI "armeabi"
  #endif
 #elif defined(__i386__)
   #define ABI "x86"
  #elif defined(__x86_64__)
   #define ABI "x86_64"
  #elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */
   #define ABI "mips64"
  #elif defined(__mips__)
   #define ABI "mips"
  #elif defined(__aarch64__)
   #define ABI "arm64-v8a"
#else
     #define ABI "unknown"
  #endif

    return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");
}

в Яве

  public class HelloJni extends Activity
 {
      /** Called when the activity is first created. */
      @Override
         public void onCreate(Bundle savedInstanceState)
        {
        super.onCreate(savedInstanceState);


    TextView  tv = new TextView(this);
    tv.setText( stringFromJNI() );
    setContentView(tv);
}


public native String  stringFromJNI();


public native String  unimplementedStringFromJNI();


static {
    System.loadLibrary("hello-jni");
}
}

Я получаю неудовлетворенную ошибку

 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.hellojni-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libhello-jni.so"
        at java.lang.Runtime.loadLibrary(Runtime.java:366)
        at java.lang.System.loadLibrary(System.java:989)
        at com.example.hellojni.HelloJni.<clinit>(HelloJni.java:64)
        at java.lang.reflect.Constructor.newInstance(Native Method)
        at java.lang.Class.newInstance(Class.java:1572)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1088)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2388)
        at android.app.ActivityThread.access$800(ActivityThread.java:148)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5312)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

Мои местные.свойства

sdk.dir=F\:\\SDK
ndk.dir=C\:\\NDK

Это не генерирует.so файлы..

1 ответ

Решение

У вас есть несколько ошибок в вашем build.gradle:

nativeLibsToJar Задача была релевантной техникой в ​​ранних версиях плагина Android для Gradle, ее не следует использовать, начиная с версии 0.7, и это может привести к ошибкам. Удалите эту задачу. Вместо этого, если вы положите.so файлы внутри jniLibs/ABI каталоги (где ABI - armeabi-v7a, x86...), они будут должным образом интегрированы в ваш APK.

Затем вы установили:

jni.srcDirs = []
jniLibs.srcDir 'src/main/libs' 

Он деактивирует встроенную интеграцию ndk с плагина gradle и позволяет библиотекам использовать gradle из libs вместо от jniLibs, Это нормально, но позже вы определяете свой модуль ndk с помощью ndk {} блок, который тогда бесполезен, удалите его.

После того, как вы очистили эти детали, вы можете позвонить ndk-build (или же ndk-build.cmd если вы используете Windows) из командной строки, из корня вашего проекта Android. Это сгенерирует ваши.so файлы внутри libs/ABI и они будут интегрированы в ваш APK, так как jniLibs.srcDir 'src/main/libs' сказал Gradle, чтобы получить эти библиотеки от libs,

Вы можете проверить, что ваши.so файлы интегрированы, открыв ваш APK в виде zip-файла; Ваши.so файлы должны присутствовать в lib/ABI,

Другие вопросы по тегам