0

我有一个用于调用回调函数的对象:

static jobject o;

我已通过指针将回调函数分配给该对象:

o=env->NewGlobalRef(callback);

相同的指针 指向使用 JNI 访问 java 代码env的函数。CallVoidMethod

env->CallVoidMethod(o, methodId, pDeviceId, deviceStatus, statusReason, connectionProgressInfo);

但是,在调用此函数时,系统崩溃了,VM 说它是对静态作业对象 o 的无效引用,然后它崩溃了。

我的代码如下:

static jint android_net_wimax_subscribeDeviceStatusChange(JNIE nv* env, jobject clazz, jobject jdeviceId, jobject callback)
{

//  LOGD(" android_net_wimax_subscribeDeviceStatusChange() ->D1");
o = env->NewGlobalRef(callback);
//o = callback;

//   LOGD(" android_net_wimax_subscribeDeviceStatusChange() ->D2");


return (jint)::SubscribeDeviceStatusChange(deviceId, fun_IndDeviceStatusUpdate);
}

void fun_IndDeviceStatusUpdate(WIMAX_API_DEVICE_ID_P pDeviceId, WIMAX_API_DEVICE_STATUS deviceStatus,
WIMAX_API_STATUS_REASON statusReason, WIMAX_API_CONNECTION_PROGRESS_INFO connectionProgressInfo)
{

JNIEnv *env = NULL; 
int nResult = -1; 


//  LOGD(" AttachCurrentThread() ->D1");

nResult = g_jVM->AttachCurrentThread(&env, NULL);

//  LOGD(" AttachCurrentThread() ->D2-%d",nResult);

if ((nResult != 0) || (env == NULL))
{ 
LOGD(" AttachCurrentThread() failed");
} 
else
{
//   LOGD(" AttachCurrentThread() ->D3");


if(o == NULL)
{

LOGD(" o is NULL ");

}
else
{
LOGD(" o is not NULL ");

}

jclass cls = env->GetObjectClass(o);

//   LOGD(" AttachCurrentThread() ->D4");
jmethodID methodId = env->GetMethodID(cls, "callback", "(Landroid/net/wimax/structs/DeviceId;III)V");

//  LOGD(" AttachCurrentThread() failed->D5");
if (methodId) {
env->CallVoidMethod(o, methodId, pDeviceId, deviceStatus, statusReason, connectionProgressInfo);
}

if (g_jVM->DetachCurrentThread() != JNI_OK) {
LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);
}
}

//   LOGD("JNI->CALLBACK->D3");

}

<<< D/wimax (1673): 在 CallVoidMethod() W/dalvikvm(1673) 之前: JNI 警告: 0x48e31dec 不是有效的 JNI 参考

W/dalvikvm(1673): 在 Ldalvik/system/NativeStart;.run ()V (CallVoidMethodV)

I/dalvikvm(1673):“Thread-55”prio=5 tid=45 RUNNABLE

我/dalvikvm(1673):| group="main" sCount=0 dsCount=0 s=N obj=0x43b6c930 self=0x306370

我/dalvikvm(1673):| sysTid=2000 nice=0 sched=0/0 cgrp=未知句柄=3194272

请帮帮我

4

2 回答 2

0

没有代码很难说,但我猜你是在创建它的函数返回 VM 之后尝试使用本地引用。

您可以从Dalvik 文档中的 Android“JNI Tips”文档(参见“Local vs. Global References”)中获得一些基本建议,并从官方 JNI 文档中获得更多详细信息。

于 2010-07-29T20:59:18.013 回答
0

尝试使用 pastebin 或预先格式化的标签。在 fun_IndDeviceStatusUpdate 中,您引用了 deviceStatusChangeCB,但我看不到它在哪里声明或分配。您使用 o 作为回调的静态全局引用。不应该在你寻找课程的地方而不是 deviceStatusChangeCB 吗?

Fadden 也是正确的,java 回调方法的第一个参数是类 android/net/wimax/structs/DeviceId 的实例。您确定 WIMAX_API_DEVICE_ID_P 是该类的一个对象实例吗?您确定错误消息(您可以发布吗?)指的是 o 而不是论点?

此外,您确定将 JVM 从调用此方法的线程中分离是安全的(例如,这是一个 Java 线程)吗?

于 2010-08-03T15:18:42.577 回答