2015-05-18 11 views
7

फ़ोल्डर संरचनाjava.lang.UnsatisfiedLinkError - एंड्रॉइड स्टूडियो में एनडीके धीरे-धीरे?

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 "."); 
} 
जावा में

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

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

इसकी फ़ाइलों .so नहीं पैदा कर रहा ..

+2

एंड्रॉइड स्टूडियो के साथ एनडीके अभी भी एक चलती लक्ष्य है, लेकिन स्पष्ट जांच यह देखने के लिए है कि क्या आप प्राप्त कर रहे हैं। इसलिए आपके एपीके में फ़ाइलें। अक्सर एंड्रॉइड स्टूडियो को यह सब अनदेखा करना, अपने आप को चलाने के लिए, और परिणाम ड्रॉप करना आसान है जहां एंड्रॉइड स्टूडियो का नवीनतम संस्करण उन्हें मिलेगा। –

+0

@ChrisStratton खुद को ndk-build कैसे चलाएं? – Asthme

+0

पाठ्यक्रम के एनएनडी दस्तावेज देखें। यह एक निष्पादन योग्य या स्क्रिप्ट है जो ndk स्थापना फ़ोल्डर की जड़ में स्थित है, जिसे आप कमांड लाइन से चला सकते हैं या स्वचालन उपकरण बना सकते हैं। –

उत्तर

4

आप में कई गलतियाँ मिल गया है हो रही है आपके build.gradle:

nativeLibsToJar कार्य ग्रेडल एंड्रॉइड प्लगइन के प्रारंभिक संस्करणों में एक प्रासंगिक तकनीक थी, इसे कम से कम 0.7 के बाद उपयोग नहीं किया जाना चाहिए और इससे बग का कारण बन सकता है, इस कार्य को हटा दें। इसके बजाए, यदि आप अपनी .so फ़ाइलों को jniLibs/ABI निर्देशिकाओं (जहां एबीआई armeabi-v7a, x86 ...) के अंदर डालते हैं, तो वे आपके एपीके के अंदर ठीक से एकीकृत हो जाएंगे।

उसके बाद, आप निर्धारित किया है:

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

यह libs से बजाय jniLibs से निर्मित Gradle प्लगइन से NDK एकीकरण और बनाने Gradle उपयोग libs निष्क्रिय कर देता। यह ठीक है, लेकिन बाद में आप अपने ndk मॉड्यूल को ndk {} ब्लॉक से परिभाषित कर रहे हैं, जो बेकार है, इसे हटा दें।

एक बार जब आप इन हिस्सों को साफ़ कर लेंगे, तो आप अपने एंड्रॉइड प्रोजेक्ट की रूट से कमांड लाइन से ndk-build (या ndk-build.cmd) या तो विंडोज़ का उपयोग कर सकते हैं। यह libs/ABI के अंदर आपकी .so फाइलें उत्पन्न करेगा और jniLibs.srcDir 'src/main/libs' के बाद से वे आपके एपीके में एकीकृत हो जाएंगे क्योंकि इन libs को libs से प्राप्त करने के लिए धीरे-धीरे कहा गया है।

आप यह जांच सकते हैं कि आपकी .so फाइलें आपके एपीके को ज़िप फ़ाइल के रूप में खोलकर एकीकृत हो जाती हैं; आपकी .so फ़ाइलों को lib/ABI के तहत उपस्थित होना होगा।

+0

बहुत बहुत धन्यवाद। यह काम किया :) – Asthme

संबंधित मुद्दे