javajava-native-interfacecocos2d-x

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


I am getting an exception when I am trying to call a non-static method in a java class from JNI.The exception I am getting is:

Can't create handler inside thread that has not called Looper.prepare()

Here is my JNI calling code:

jclass mClass = env->FindClass("com/secrethq/match3/Match3Activity");

jmethodID constructor = env->GetMethodID( mClass, "<init>", "()V");
CCLog("jClass Located?");

jobject object = env->NewObject(mClass, constructor);
mid = env->GetMethodID(mClass, "onClickPostStatusUpdate", "(I)V");


CCLog("mID: %d", mid);

if (mid!=0)
env->CallVoidMethod(mClass, mid, object, score);
        //-----------------------------------------------------------
CCLog("Finish");
if(isAttached)
    jvm->DetachCurrentThread();

and this is my method in java class:

private void onClickPostStatusUpdate(int score) {
    System.out.println("Match3Activity.onClickPostStatusUpdate()");
    performPublish(PendingAction.POST_STATUS_UPDATE, canPresentShareDialog);
}

Here is the Logcat output:

06-22 20:20:39.342: E/AndroidRuntime(14899): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
06-22 20:20:39.342: E/AndroidRuntime(14899):    at android.os.Handler.<init>(Handler.java:121)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at android.app.Activity.<init>(Activity.java:772)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at org.cocos2dx.lib.Cocos2dxActivity.<init>(Cocos2dxActivity.java:37)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at com.secrethq.match3.Match3Activity.<init>(Match3Activity.java:45)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at org.cocos2dx.lib.Cocos2dxRenderer.nativeTouchesEnd(Native Method)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at    org.cocos2dx.lib.Cocos2dxRenderer.handleActionUp(Cocos2dxRenderer.java:129)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at     org.cocos2dx.lib.Cocos2dxGLSurfaceView$9.run(Cocos2dxGLSurfaceView.java:258)
06-22 20:20:39.342: E/AndroidRuntime(14899):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462) 
06-22 20:20:39.342: E/AndroidRuntime(14899):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

Solution

  • The line:

    jobject object = env->NewObject(mClass, constructor);
    

    attempts to instantiate an Activity. In general, you aren't supposed to instantiate Activities by hand, but are meant to create them using designated Android APIs, e.g. Context.startActivity.

    By circumventing the API, you've gotten yourself in a situation where you create an Activity in a thread which does not support the creation of an Activity.

    That's the cause of the error. But also: you probably want to rethink the code as a whole. Not sure what you're trying to do, but it doesn't seem like the pattern you're using is the right one.