Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.UnsatisfiedLinkError - NDK in android studio gradle?

Folder structure

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

in 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')
}


}

in Android.mk

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

in 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 ".");
}

in java

  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");
}
}

I am getting unsatisfied error

 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)

My local.properties

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

Its not generating .so files ..

like image 379
Asthme Avatar asked May 18 '15 04:05

Asthme


1 Answers

You've got several mistakes in your build.gradle:

The nativeLibsToJar task was a relevant technique in early versions of the gradle android plugin, It shouldn't be used since at least 0.7 and it may lead to bugs, remove this task. Instead, if you put your .so files inside jniLibs/ABI directories (where ABI is armeabi-v7a, x86...), they will get properly integrated inside your APK.

Then, you have set:

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

It deactivates the built-in ndk integration from the gradle plugin and make gradle use libs from libs instead of from jniLibs. That's fine, but later you're defining your ndk module with a ndk {} block, which is useless then, remove it.

Once you've cleaned these parts, you can call ndk-build (or ndk-build.cmd if you're using Windows) from command line, from the root of your Android project. It will generate your .so files inside libs/ABI and they will get integrated into your APK since jniLibs.srcDir 'src/main/libs' told gradle to get these libs from libs.

You can check that your .so files get integrated by opening your APK as a zip file; Your .so files have to be present under lib/ABI.

like image 90
ph0b Avatar answered Sep 29 '22 18:09

ph0b