2015-05-18 10 views
7

Struttura delle cartellejava.lang.UnsatisfiedLinkError - NDK nel grader di Android Studio?

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

sto ottenendo errore insoddisfatto

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) 

miei local.properties

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

La sua non è la generazione di file .so ..

+2

NDK con Android Studio è ancora un bersaglio mobile, ma il controllo evidente è per vedere se stai ricevendo i file .so nel tuo apk. Spesso è più facile dire a Android Studio di ignorare tutto, eseguire ndk-build te stesso e rilasciare il risultato ovunque l'ultima versione di Android Studio li trovi. –

+0

@ChrisStratton come eseguire ndk-build me stesso? – Asthme

+0

Vedere naturalmente la documentazione di ndk. È un eseguibile o uno script situato nella directory principale della cartella di installazione di ndk, che può essere eseguito da una riga di comando o costruire uno strumento di automazione. –

risposta

4

hai parecchi errori nel vostro build.gradle:

L'attività nativeLibsToJar era una tecnica pertinente nelle prime versioni del plugin gradle per Android, non dovrebbe essere utilizzata da almeno 0,7 e potrebbe portare a bug, rimuovere questa attività. Invece, se metti i tuoi file .so nelle directory jniLibs/ABI (dove ABI è armeabi-v7a, x86 ...), verranno integrati correttamente nel tuo APK.

Poi, è stata impostata:

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

disattiva l'uso librerie Gradle built-in di integrazione NDK dal plugin Gradle e fare da libs invece che da jniLibs. Va bene, ma dopo si sta definendo il modulo ndk con un blocco ndk {}, che è quindi inutile, rimuoverlo.

Dopo aver pulito queste parti, è possibile chiamare ndk-build (o ndk-build.cmd se si utilizza Windows) dalla riga di comando, dalla radice del progetto Android. Genera i tuoi file .so all'interno di libs/ABI e verranno integrati nel tuo APK dal jniLibs.srcDir 'src/main/libs' detto a gradle per ottenere queste librerie da libs.

È possibile verificare che i file .so vengano integrati aprendo l'APK come file zip; I tuoi file .so devono essere presenti sotto lib/ABI.

+0

grazie mille. è funzionato :) – Asthme