3

Edit: So the issue was on the Java side. The purchase finished listener wasn't being called. This was very helpful: IabHelper PurchaseFinishedListener

My Cocos2dx game runs fine on Android and iOS for the most part. Only think giving me trouble is Android In-App Billing.

I'm using JNI to call from C++ to Java. The Java code goes back and forth w/ Google Play billing system and ultimately calls back to the C++ code indicating how much treasure to give to the user (amount successfully purchased).

The call from Java back to C++ is doing something very strange. The C++ code that runs should update the display of two things. However it only updates one and it's not consistent. Also multiple calls from Java to C++ result in CCNodes ignoring touches and doing other strange things.

After reading up on similar issues I realized that perhaps the Java to C++ call wasn't on the main/UI thread. So I tried to fix that like this:

// Java code
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
       public void onConsumeFinished(Purchase purchase, IabResult result) {
          if (result.isSuccess()) {
              String sku = purchase.getSku();
              if (sku.equals(IAB_ID_ABC)) {
                me.runOnUiThread(new Runnable() {
                    public void run() {
                        callCppMethodFromJava_giveUserABC();
                    }
                 });
               }
        }
    };

Here I'm trying to call giveUserABC on the main/UI thread. giveUserABC is called however it's exhibiting strange behavior as described above.

Another thing I tried is posting a notification via CCNotificationCenter in giveUserABC. This was a shot in the dark but I read that it worked somewhere for someone.

Unfortunately none of this has fixed the strange behavior. Any help in understanding and fixing this situation is greatly appreciated!

Community
  • 1
  • 1
SundayMonday
  • 19,147
  • 29
  • 100
  • 154
  • Could you post the C++ part? Especially the callback after purchase. – Losiowaty Dec 17 '13 at 11:59
  • @Losiowaty Are you interested in the C++ syntax or something else? The syntax wasn't too much of issue. Name your function something like `void Java_org_cocos2dx_lib_Cocos2dxActivity_MyAwesomeFunction`. In the Java code you would have `public static native void MyAwesomeFunction();` – SundayMonday Dec 20 '13 at 17:52

1 Answers1

13

From my experience, you should run it at GLThread:

me.runOnGLThread(new Runnable() {
  public void run() {
    callCppMethodFromJava_giveUserABC();
  }
});

As we know, the UiThread is the main thread of an Android app, while the Cocos2dxGLSurfaceView is usually run at GL thrread.

So if you want to call from Java to C++, you should call it at GL thread. While calling from C++ to Java, you should usually call it at Ui thread. It's right in most cases from my experience.

For more information, runOnGLThread method is not an api of Android, it is achieved org.cocos2dx.lib.Cocos2dxActivity.java in cocos2d-x project.

From the source code, you can easily find that, using Cocos2dxGLSurfaceView.getInstance().queueEvent() instead of this.runOnGLThread() is also ok.

pktangyue
  • 8,326
  • 9
  • 48
  • 71