Android和UnsatisfiedLinkError

时间:2011-05-20 04:18:12

标签: java-native-interface android-ndk

我对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()注册方法。

1 个答案:

答案 0 :(得分:1)

初始化JNINativeMethod数组时有两个额外的括号,此代码不应编译。

检查RegisterNatives()的返回码,成功时应为零。

如果你正在编译C ++代码,你应该声明本机方法extern "C"以避免它们被破坏。