2015-05-18 105 views
7

文件夾結構java.lang.UnsatisfiedLinkError - android studio gradle中的NDK?

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) 

你好-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 "."); 
} 
在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"); 
} 
} 

我越來越不滿意錯誤

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) 

我local.properties

​​

它不產生.so文件..

+2

NDK與Android Studio仍然是一個移動的目標,但顯而易見的檢查是看你是否得到.so文件在你的apk。通常情況下,告訴Android Studio全部忽略它,自己運行ndk-build並在最新版本的Android Studio找到它們時放棄結果會更容易。 –

+0

@ChrisStratton如何運行ndk-build自己? – Asthme

+0

查看當然的ndk文檔。它是位於ndk安裝文件夾根目錄下的可執行文件或腳本,可以從命令行運行或構建自動化工具。 –

回答

4

在您收到幾個錯誤你build.gradle:

nativeLibsToJar任務是gradle android插件早期版本中的一項相關技術,不應該使用它,因爲至少0.7,它可能會導致錯誤,刪除此任務。相反,如果您將.so文件放入jniLibs/ABI目錄(其中ABI是armeabi-v7a,x86 ...),它們將在您的APK中正確集成。

然後,您已設置:

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

libs而不是從jniLibs停用內置從gradle這個插件NDK集成,並利用gradle這個庫。這很好,但後來你用一個ndk {}塊來定義你的ndk模塊,然後將它刪除。

清理完這些零件後,您可以從命令行調用ndk-build(或ndk-build.cmd,如果您使用的是Windows),那麼您可以從Android項目的根目錄中調用這些零件。它會在libs/ABI內生成你的.so文件,並且它們會被集成到你的APK中,因爲jniLibs.srcDir 'src/main/libs'告訴gradle從libs獲得這些庫。

您可以通過打開您的APK作爲zip文件來檢查您的.so文件是否已集成;您的.so文件必須在lib/ABI下出現。

+0

非常感謝。它的工作:) – Asthme

相關問題