I have a C thread that is making requests and receiving updates from a server. The updates are sent to Java through JNI calls. My problem happens when I'm receiving a player's inventory which can contain up to 100 items (100 responses from the server, I cannot modify this part). Sometimes the problem happens, sometimes not but the bigger the inventory is, the more often I have this issue.
I don't get any exception in the logcat except the following message :
06-10 10:09:46.085: I/Choreographer(23815): Skipped 87 frames! The application may be doing too much work on its main thread.
And then my app closes. I also need to say that even when I comment the lines where I update the UI with runOnUiThread
the app crash.
I tried to check if I'm on the UI Thread when I return to Java with JNI but Looper.myLooper() == Looper.getMainLooper()
return false
.
Anyone experienced the same problem ? Are the C threads related to the main thread somehow ? Thanks
EDIT
When I receive an update from the server the following calls are made :
- From a Java Thread (not the UI thread) : call a C function named
notifyAll
From
notifyAll
call a C function namedupdate
which will call its equivalent in Java (see code below)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(); } }
I think the problem is at this line gCachedJVM->GetEnv((void **) &env, JNI_VERSION_1_2);
and maybe GetEnv return a pointer for the UI thread. Could that be the problem ? How can I fix this ?