我在调用从 C++ 启用 GPS 定位时遇到问题。我使用 SWIG 生成了 JNI 包装器。日志猫说:
01-02 17:14:03.816: D/dalvikvm(6165): Trying to load lib /data/data/com.example.swig/lib/libcppinterface.so 0x44e7ebf0
01-02 17:14:03.976: D/dalvikvm(6165): Added shared lib /data/data/com.example.swig/lib/libcppinterface.so 0x44e7ebf0
01-02 17:14:04.886: W/dalvikvm(6165): JNI WARNING: 0x44e8bb48 is not a valid JNI reference
01-02 17:14:04.886: W/dalvikvm(6165): in Lcom/example/swig/cpplib/cppinterfaceJNI;.LocationSpotter_refresh (JLcom/example/swig/cpplib/LocationSpotter;)V (CallVoidMethodV)
01-02 17:14:04.886: I/dalvikvm(6165): "main" prio=5 tid=1 RUNNABLE
01-02 17:14:04.886: I/dalvikvm(6165): | group="main" sCount=0 dsCount=0 s=N obj=0x4001d8e0 self=0xccb0
01-02 17:14:04.886: I/dalvikvm(6165): | sysTid=6165 nice=0 sched=0/0 cgrp=default handle=-1345026008
01-02 17:14:04.886: I/dalvikvm(6165): | schedstat=( 226108400 549900071 66 )
01-02 17:14:04.886: I/dalvikvm(6165): at com.example.swig.cpplib.cppinterfaceJNI.LocationSpotter_refresh(Native Method)
01-02 17:14:04.896: I/dalvikvm(6165): at com.example.swig.cpplib.LocationSpotter.refresh(LocationSpotter.java:56)
01-02 17:14:04.896: I/dalvikvm(6165): at com.example.swig.MainActivity.onCreate(MainActivity.java:50)
01-02 17:14:04.896: I/dalvikvm(6165): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-02 17:14:04.896: I/dalvikvm(6165): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
01-02 17:14:04.896: I/dalvikvm(6165): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
01-02 17:14:04.896: I/dalvikvm(6165): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
01-02 17:14:04.896: I/dalvikvm(6165): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-02 17:14:04.896: I/dalvikvm(6165): at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 17:14:04.896: I/dalvikvm(6165): at android.os.Looper.loop(Looper.java:123)
01-02 17:14:04.896: I/dalvikvm(6165): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-02 17:14:04.896: I/dalvikvm(6165): at java.lang.reflect.Method.invokeNative(Native Method)
01-02 17:14:04.896: I/dalvikvm(6165): at java.lang.reflect.Method.invoke(Method.java:521)
01-02 17:14:04.896: I/dalvikvm(6165): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-02 17:14:04.896: I/dalvikvm(6165): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-02 17:14:04.896: I/dalvikvm(6165): at dalvik.system.NativeStart.main(Native Method)
01-02 17:14:04.906: E/dalvikvm(6165): VM aborting
我用这一行触发来自 Java 的调用:
LocationSpotter.getLocationSpotter().refresh();
getLocationSpotter() 在 C++ 中触发此代码,该代码创建一个作业对象 (jSpotter):
// Retrieve the current JNIEnv* with the cached JVM
JNIEnv* env;
AndroidLocationSpotter::cachedJVM->AttachCurrentThread(&env, NULL);
jclass clazz = env->FindClass("com/example/swig/AndroidLocationSpotter");
jmethodID construct = env->GetMethodID(clazz, "<init>", "()V");
jSpotter = env->NewObject(clazz, construct);
并在方法 refresh() 触发此代码后,使应用程序崩溃:
// Retrieve the current JNIEnv* with the cached JVM
JNIEnv* env;
AndroidLocationSpotter::cachedJVM->AttachCurrentThread(&env, NULL);
jclass clazz = env->FindClass("com/example/swig/AndroidLocationSpotter");
jmethodID refresh = env->GetMethodID(clazz, "refresh", "()V");
env->CallVoidMethod(jSpotter, refresh); // The line where the crash happens
我还需要提到的是,我在 JNI_OnLoad 函数中启动了“cachedJVM”。希望有人可以帮助我,谢谢
编辑
工作代码:
// Retrieve the current JNIEnv* with the cached JVM
JNIEnv* env;
AndroidLocationSpotter::cachedJVM->AttachCurrentThread(&env, NULL);
jclass clazz = env->FindClass("com/example/swig/AndroidLocationSpotter");
jmethodID construct = env->GetMethodID(clazz, "<init>", "()V");
jSpotter = env->NewObject(clazz, construct);
jSpotter = env->NewGlobalRef(jSpotter);