1

我正在尝试运行我的应用程序,但是每当我调用本机函数时,它都会给我一个错误并且程序崩溃。我确信这与我在 Java 或 C 中如何命名某些东西有关。

这是我对 Java 函数的调用:

package my.commander;

public class RelayAPIModel {

    public static class NativeCalls {

        static {
            System.loadLibrary( "RelayAPI");
        }

        public native static byte InitRelayJava();

        public native static void FreeRelayJava();
    }

以下是.c文件中的函数:

void Java_my_commander_RelayAPIModel_FreeRelayJava( JNIEnv * env, jobject this ) {
    RelayAPI_DataValid = 0;
    RelayAPI_SetBaud = 0;
    RelayAPI_get = 0;
    RelayAPI_put = 0;
    RelayAPI_flush = 0;
    RelayAPI_delay = 0;
    RelayAPI_initilized = 0;
}


BYTE Java_my_commander_RelayAPIModel_InitRelayJava( JNIEnv *env, jobject obj  ) {
    ...
    ...
}

它们在.h文件中:

void Java_my_commander_RelayAPIModel_FreeRelayJava( JNIEnv * env, jobject obj );

BYTE Java_my_commander_RelayAPIModel_InitRelayJava( JNIEnv *env, jobject obj );

这是我的LogCat:

08-01 09:58:21.933: E/AndroidRuntime(17170): FATAL EXCEPTION: main
08-01 09:58:21.933: E/AndroidRuntime(17170): java.lang.UnsatisfiedLinkError: InitRelayJava
08-01 09:58:21.933: E/AndroidRuntime(17170):    at my.eti.commander.RelayAPIModel$NativeCalls.InitRelayJava(Native Method)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at my.eti.commander.MainMenu.initMain(MainMenu.java:241)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at my.eti.commander.MainMenu.onCreate(MainMenu.java:81)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.os.Looper.loop(Looper.java:130)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at android.app.ActivityThread.main(ActivityThread.java:3683)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at java.lang.reflect.Method.invokeNative(Native Method)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at java.lang.reflect.Method.invoke(Method.java:507)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-01 09:58:21.933: E/AndroidRuntime(17170):    at dalvik.system.NativeStart.main(Native Method)

我现在想澄清一下,我已尝试将 C 方法名称更改为Java_my_commander_RelayAPIModel_NativeCalls_FreeRelayJavaand Java_my_commander_RelayAPIModel_NativeCalls_InitRelayJava。该应用程序仍然无法启动,这就是 LogCat:

08-01 11:22:10.735: E/AndroidRuntime(17441): FATAL EXCEPTION: main
08-01 11:22:10.735: E/AndroidRuntime(17441): java.lang.UnsatisfiedLinkError: InitRelayJava
08-01 11:22:10.735: E/AndroidRuntime(17441):    at my.eti.commander.RelayAPIModel$NativeCalls.InitRelayJava(Native Method)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at my.eti.commander.MainMenu.initMain(MainMenu.java:241)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at my.eti.commander.MainMenu.onCreate(MainMenu.java:81)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.os.Looper.loop(Looper.java:130)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at android.app.ActivityThread.main(ActivityThread.java:3683)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at java.lang.reflect.Method.invokeNative(Native Method)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at java.lang.reflect.Method.invoke(Method.java:507)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-01 11:22:10.735: E/AndroidRuntime(17441):    at dalvik.system.NativeStart.main(Native Method)


现在,我认为错误在于上面的代码。如果你们都认为这没什么问题,我将在此处添加更多信息,以防万一问题出在其他地方。

我正在创建的这个应用程序使用上面的函数来调用一个已经使用了一段时间的库。该库以前用于调用 Palm Pilot 程序中的函数,该程序利用了 Palm 的蓝牙功能。由于 Android 设备具有不同的蓝牙库/功能,我将代码添加到本机库以调用 BACK 到 java 代码,以访问 Android 设备的蓝牙功能。我不想在这里发布与此相关的所有代码,但如果有人觉得需要发布它,我会的。

4

2 回答 2

6

错误消息说它位于:

my.eti.commander.RelayAPIModel$NativeCalls.InitRelayJava (Native Method)

因此,请确保:

  • native方法声明确实在类内部RelayAPIModel,而不是RelayAPIModel.NativeCalls嵌套类内部。
  • Java 端的包名my.commandermy.eti.commander

编辑:或者你可以在 C 端修复它。如果你想在嵌套类中创建本地方法,它的正确名称应该是:

Java_my_commander_RelayAPIModel_00024NativeCalls_InitRelayJava()

00024 是 $ 字符的代码,它是 Java 内部的嵌套类分隔符。此外,第二个参数 ( jobject Obj) 的含义会有所不同 - 不是 的this指针/类指针RelayAPIModel,而是RelayAPIModel.NativeCalls. 您将无法使用它来解析/调用RelayAPIModel.

于 2012-08-01T15:53:00.587 回答
5

您可以使用 javah 生成具有正确命名的本机文件的 .h 文件:

javah -jni -classpath bin/classes com.example.app.MyClass
于 2012-08-01T15:39:15.213 回答