我对Android和我正在使用的JNI库有一个特殊的问题。 JNI库名为libBase.so,并且正确包含在APK中。我能够做System.loadLibrary(“Base”)并且库被加载并且可以毫无问题地使用。
请考虑以下代码段:
/* NativeObject.java */
public class NativeObject
{
/* ... */
static
{
System.loadLibrary("Base");
}
}
/* ObjectUtil.java */
public class ObjectUtil
{
public static native NativeObject readNative(String path);
public static native void writeNative(String path, NativeObject obj);
}
当我尝试在程序开头执行ObjectUtil.readNative()时,我在logcat中遇到以下问题:
05-19 18:57:38.508: WARN/dalvikvm(365): No implementation found for native Lcom/navimatics/base/ObjectUtil;.readNative (Ljava/lang/String;)Lcom/navimatics/base/NativeObject;
05-19 18:59:15.409: ERROR/AndroidRuntime(365): java.lang.UnsatisfiedLinkError: readNative
我的理解是因为ObjectUtil类引用了NativeObject,所以加载ObjectUtil类应该强制加载NativeObject类,从而执行执行System.LoadLibrary()调用的NativeObject静态初始化程序。目前尚不清楚为什么我会得到上述的logcat消息。
但是,如果我将ObjectUtil.java修改为如下所示,则没有异常并且程序可以正常工作:
/* ObjectUtil.java */
public class ObjectUtil
{
public static native NativeObject readNative(String path);
public static native void writeNative(String path, NativeObject obj);
static
{
System.loadLibrary("Base");
}
}
如果我这样做,它也有效:
/* ObjectUtil.java */
public class ObjectUtil extends NativeObject
{
public static native NativeObject readNative(String path);
public static native void writeNative(String path, NativeObject obj);
}
对此的任何帮助将不胜感激。
更新 我被要求的原生代码是:
static jobject JNICALL readNative(JNIEnv *env, jclass jcls, jstring jpath)
{
// ...
}
static void JNICALL writeNative(JNIEnv *env, jclass jcls, jstring jpath, jobject jobj)
{
// ...
}
static JNINativeMethod methods[] =
{
{ "readNative", "(Ljava/lang/String;)Lcom/navimatics/base/NativeObject;", readNative },
{ "writeNative", "(Ljava/lang/String;Lcom/navimatics/base/NativeObject;)V", writeNative },
};
使用JNIEnv.RegisterNatives()注册方法。
答案 0 :(得分:1)
初始化JNINativeMethod数组时有两个额外的括号,此代码不应编译。
检查RegisterNatives()的返回码,成功时应为零。
如果你正在编译C ++代码,你应该声明本机方法extern "C"
以避免它们被破坏。