0

私はコールバック関数を呼び出すために使用されるオブジェクトを持っています:

static jobject o;

私はポインターを介してそのオブジェクトにコールバック関数を割り当てました:

o=env->NewGlobalRef(callback);

同じポインター は、 JNI を使用して Java コードに到達するenv関数を指しています。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

私/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ヒント」ドキュメント(「ローカルvs.グローバルリファレンス」を参照)からいくつかの基本的なアドバイスを得ることができ、公式のJNIドキュメントからより詳細な情報を得ることができます。

于 2010-07-29T20:59:18.013 に答える
0

ペーストビンまたはフォーマット済みタグを使用してみてください。fun_IndDeviceStatusUpdate で deviceStatusChangeCB を参照していますが、それが宣言または割り当てられている場所がわかりません。コールバックへの静的グローバル参照として o を使用します。deviceStatusChangeCB ではなく、クラスを探す場所であるべきではありませんか?

Java コールバック メソッドの最初の引数がクラス android/net/wimax/structs/DeviceId のインスタンスであるという Fadden の意見も正しいです。WIMAX_API_DEVICE_ID_P がそのクラスのジョブジェクト インスタンスであると確信していますか? エラーメッセージ (投稿できますか?) は、引数ではなく o を参照していますか?

また、このメソッドが呼び出されているスレッドから JVM を切り離しても安全ですか (たとえば、これは Java スレッドですか)?

于 2010-08-03T15:18:42.577 に答える