回调期间的引用无效

时间:2010-07-29 13:10:04

标签: android callback java-native-interface android-2.2-froyo

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

static jobject o;

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

o=env->NewGlobalRef(callback);

相同的指针env指向使用JNI到达java代码的函数CallVoidMethod

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

然而,在调用此函数时,系统崩溃,VM表示它是对静态jobject 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

     

I / dalvikvm(1673):| group =“main”sCount = 0 dsCount = 0 s = N obj = 0x43b6c930 self = 0x306370

     

I / dalvikvm(1673):| sysTid = 2000 nice = 0 sched = 0/0 cgrp = unknown handle = 3194272

请帮助我

2 个答案:

答案 0 :(得分:0)

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

您可以从Dalvik docs中的Android“JNI Tips”文档中获得一些基本建议(请参阅“本地与全局参考”),以及来自官方JNI文档的更详细信息。

答案 1 :(得分:0)

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

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

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