我有一个 C 线程正在发出请求并从服务器接收更新。更新通过 JNI 调用发送到 Java。当我收到一个玩家的库存最多可以包含 100 件物品(来自服务器的 100 个响应,我无法修改这部分)时,我的问题就会发生。有时会出现问题,有时不会,但库存越大,我遇到此问题的频率越高。
除了以下消息外,我在 logcat 中没有任何异常:
06-10 10:09:46.085: I/Choreographer(23815): Skipped 87 frames! The application may be doing too much work on its main thread.
然后我的应用程序关闭。我还需要说,即使我评论了我用runOnUiThread
应用程序崩溃更新 UI 的行。
Looper.myLooper() == Looper.getMainLooper()
当我使用 JNI 返回 Java 但return时,我试图检查我是否在 UI 线程上false
。
有人遇到过同样的问题吗?C线程是否以某种方式与主线程相关?谢谢
编辑
当我收到来自服务器的更新时,会进行以下调用:
- 从 Java 线程(不是 UI 线程):调用名为
notifyAll
从
notifyAll
调用一个名为的 C 函数update
,它将在 Java 中调用它的等价物(见下面的代码)void UpdateListenerWrapper::update(Update& u) { // Retrieve the current JNIEnv* with the cached JVM int status; JNIEnv* env; bool isAttached = false; status = gCachedJVM->GetEnv((void **) &env, JNI_VERSION_1_2); if(status < 0) { __android_log_print(ANDROID_LOG_ERROR, "UpdateListenerWrapper", "Failed to get JNI environment"); status = gCachedJVM->AttachCurrentThread(&env, NULL); if(status < 0) { __android_log_print(ANDROID_LOG_ERROR, "UpdateListenerWrapper", "Failed to attach current thread"); return; } isAttached = true; } jmethodID update = env->GetMethodID(gClazzUpdateListenerWrapper, "update", "(J)V"); // J stands for Java long type // Call Java method update from jUpdateListener object env->CallVoidMethod(jUpdateListener, update, (jlong)(intptr_t)&u); // Pointer as agument, we'll build the Update object in Java if (isAttached) { gCachedJVM->DetachCurrentThread(); } }
我认为问题出在这一行gCachedJVM->GetEnv((void **) &env, JNI_VERSION_1_2);
,也许 GetEnv 返回 UI 线程的指针。这可能是问题吗?我怎样才能解决这个问题 ?