我在src / main中创建了JNI文件夹,并使用javah成功生成了c头文件。然后我实现如下:
#include <jni.h>
#include <string.h>
JNIEXPORT jstring JNICALL Java_com_kxiaozao_kxz_KXZSDK_KXZSDKInterface_encode (JNIEnv *env, jobject thisz, jstring jsonString) {
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
我的Android.mk文件是:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := kxz_encoder
LOCAL_SRC_FILES := kxz_encoder.c
include $(BUILD_SHARED_LIBRARY)
运行ndk-build后,在libs / armeabi
中生成.so文件另外,我在活动中添加了以下几行。
static {
System.loadLibrary("kxz_encoder");
}
在Kitkat上运行此应用程序时出现以下错误:
java.lang.UnsatisfiedLinkError: Couldn't load kxz_encoder from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.kxiaozao.kxz-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.kxiaozao.kxz-2, /vendor/lib, /system/lib]]]: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:358)
at java.lang.System.loadLibrary(System.java:526)
at com.kxiaozao.kxz.KXZFrontEnd.ViewController.KXZRecommendationVC.<clinit>(KXZRecommendationVC.java:258)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1559)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2101)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
我检查了Runtime.java
中发生错误的函数void loadLibrary(String libraryName, ClassLoader loader) {
if (loader != null) {
String filename = loader.findLibrary(libraryName);
if (filename == null) {
throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
" from loader " + loader +
": findLibrary returned null");
}
String error = doLoad(filename, loader);
if (error != null) {
throw new UnsatisfiedLinkError(error);
}
return;
}
String filename = System.mapLibraryName(libraryName);
List<String> candidates = new ArrayList<String>();
String lastError = null;
for (String directory : mLibPaths) {
String candidate = directory + filename;
candidates.add(candidate);
if (IoUtils.canOpenReadOnly(candidate)) {
String error = doLoad(candidate, loader);
if (error == null) {
return; // We successfully loaded the library. Job done.
}
lastError = error;
}
}
if (lastError != null) {
throw new UnsatisfiedLinkError(lastError);
}
throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
}
似乎在第三行中,filename为null。谁能帮我解决这个问题? 谢谢!
答案 0 :(得分:1)
当前版本的android studio不提供NDK支持。你可以参考以下链接。 https://developer.android.com/sdk/installing/studio.html
答案 1 :(得分:0)
我认为你不能。截至目前,Android工作室不支持/包含NDK。你不能写&amp;测试jni代码。相反,您可以使用so文件(如果已经构建)
答案 2 :(得分:0)
您需要在JNI文件夹中创建另一个虚拟C文件。目前不支持NDK,但有一种解决方法可以将NDK与Android Studio配合使用。在JNI文件夹中创建另一个C文件,并将C文件留空。此外,您的所有.mk文件都会被忽略。您可以通过停用默认的NDK集成使Android Studio / gradle重用它们,让它自己调用ndk-build(.cmd),并使用标准的libs / location来集成.so文件:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig{
minSdkVersion 15
targetSdkVersion 19
versionCode 101
versionName "1.0.1"
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = [] //disable automatic ndk-build call
}
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
答案 3 :(得分:0)