Неверная ссылка во время обратного вызова - PullRequest
0 голосов
/ 29 июля 2010

У меня есть объект, который используется для вызова функций обратного вызова:

static jobject o;

Я назначил функцию обратного вызова этому объекту через указатель:

o=env->NewGlobalRef(callback);

Тот же указатель,env указывает на функцию CallVoidMethod, которая использует JNI для доступа к Java-коду.

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 </p>

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 = неизвестный дескриптор = 3194272

Пожалуйста, помогите мне

Ответы [ 2 ]

0 голосов
/ 03 августа 2010

Попробуйте использовать pastebin или предварительно отформатированный тег.В fun_IndDeviceStatusUpdate вы ссылаетесь на deviceStatusChangeCB, но я не вижу, где он объявлен или назначен.Вы используете o в качестве статической глобальной ссылки на обратный вызов.Разве не должно быть там, где вы ищете класс, а не deviceStatusChangeCB?

Фадден также прав, что первым аргументом метода обратного вызова java является экземпляр класса android / net / wimax / structs / DeviceId.Вы уверены, что WIMAX_API_DEVICE_ID_P является экземпляром задания этого класса?Вы уверены, что сообщение об ошибке (вы можете опубликовать это?) Ссылается на o, а не на аргумент?

Кроме того, вы уверены, что безопасно отсоединить JVM от потока, из которого вызывается этот метод(например, это поток Java)?

0 голосов
/ 30 июля 2010

Без кода на это трудно сказать, но я думаю, что вы пытаетесь использовать локальную ссылку после того, как функция, в которой она была создана, вернулась на ВМ.

Вы можете получить некоторые базовые советы из документа Android JNI Tips в Dalvik docs (см. «Местные и глобальные ссылки»), а также более подробную информацию из официальной документации JNI.

...