Passing an integer with JNI

this is what I have in my AppActivity, how do I get the integer parameter (score) from .cpp to .java ?

public static void shareMyScore(int score)
{

}

Sorry, forgot about integer :slight_smile:

C++

void AdHelper::shareMyScore(int score)
{
    cocos2d::JniHelper::callStaticVoidMethod(“org.cocos2dx.cpp.AppActivity”, “shareMyScore”, score);
}

Java

public static void shareMyScore(final int score) {
    final AppActivity activity = ((AppActivity)Cocos2dxHelper.getActivity());

    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            // your code
        }
    });
}
1 Like

I was looking at some other code , is
final AppActivity activity = ((AppActivity)Cocos2dxHelper.getActivity()); does the same thing as
private static Activity activity = AppAcitivity.getInstance(); ?

also in this example I was following they called method.env->DeleteLocalRef(stringMessage); do I have to do something similar for the integer im passing in ?

yes AppAcitivity.getInstance() the same

no, for int no need.

1 Like

ok thanks verymuch for your help!

also is
“acitvity.runOnGlThread”

the same thing as “activity.runOnUiThread” ??

Sorry, for your case runOnUiThread is needed.

  • runOnGlThread - use this to call C++ code from Java, so C++ code will be executed in cocos2d thread (GL)
  • runOnUiThread - use this to call Java code from C++, so Java code will be executed in Java’s UI thread
1 Like

ok thanks once again :smiley::+1:

Glad to help :wink:

1 Like

Hello @dimon4eg could you help me with this ? inside the onConsentFormLoaded method it says for “variable ‘form’ is accessed from within inner class must be declared final” but then when I declare it final it then shows a error “variable ‘form’ might not have been initialized” I tried declaring 'private static ConsentForm form" at the top of my class but then it gives a error saying about placing android context classes inside a static field will result in a memory leak so im not sure where to go from here ?

public static void settings()
{
final AppActivity activity = ((AppActivity) Cocos2dxHelper.getActivity());

activity.runOnUiThread(new Runnable() {
@Override
public void run() {

URL privacyUrl = null;
try {
// TODO: Replace with your app’s privacy policy URL.
privacyUrl = new URL(“https://privacy-policy”);
} catch (MalformedURLException e) {
e.printStackTrace();
}

ConsentForm form = new ConsentForm.Builder(getContext(), privacyUrl).withListener(new ConsentFormListener() {

@Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
Log.i(“consent”, “consent loaded”);
form.show();
}

@Override
public void onConsentFormOpened() {
// Consent form was displayed.
}

@Override
public void onConsentFormClosed(ConsentStatus consentStatus, Boolean userPrefersAdFree) {

Log.i(“consent”, "consent form was just closed the consent status is " + consentStatus);

if(consentStatus == ConsentStatus.PERSONALIZED) {
Log.i(“consent”, “PERSONALIZED”);

AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);

} else if(consentStatus == ConsentStatus.NON_PERSONALIZED){
Log.i(“consent”, “NON_PERSONALIZED”);

Bundle extras = new Bundle();
extras.putString(“npa”, “1”);
AdRequest adRequest = new AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter.class, extras).build();
adView.loadAd(adRequest);

}

}

@Override
public void onConsentFormError(String errorDescription) {
// Consent form error.
Log.i(“consent”, errorDescription);
}
})
.withPersonalizedAdsOption().withNonPersonalizedAdsOption().build();

form.load();
}
});
}

is it possible to make the java method non static ? or what is the reason if there is one that the method has to be declared static ?

So this doesn’t work?

final ConsentForm form = new ConsentForm.Builder(
1 Like

No, it then says in side my onConsentFormLoaded that “form” may not have been initialized and it won’t compile

I also do the following for JNI

  1. check, log, clear exceptions
  2. release memory for objects (e.g. when passing jstring)
1 Like

Do we have to release memory for passing an integer ? And what is the code for “check, log, clear exception”?

How do you release memory when passing a jstring ? and what exactly do you mean by “check, log, clear exception” ?

You can find more info by searching for “JNI release memory”

JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, ...))
{
    jstring jStr = t.env->NewStringUTF(pszValue);
   .....
    t.env->DeleteLocalRef(jStr);
}

You can find more info by searching for “JNI check exception”

if (t.env->ExceptionCheck())
{
    t.env->ExceptionDescribe();
    t.env->ExceptionClear();
}

Most likely you don’t need to release memory when passing an integer.

Most likely, you are using

jint - no release required.

But in the unlikely case you want to pass

java.lang.Integer - yes

1 Like

What would the reverse of this be? Like how would you pass an integer from Java to C++?

1 Like

@doom_monsta you can find examples in cocos2d.

Here is C++ part, example from cocos2d-x\cocos\platform\android\CCDevice-android.cpp:

extern "C"
{
    /**
    * this method is called by java code to init width, height and pixels data
    */
    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxBitmap_nativeInitBitmapDC(JNIEnv*  env, jobject thiz, int width, int height, jbyteArray pixels)
    {
        ...
    }
};

Java part, example from cocos2d-x\cocos\platform\android\java\src\org\cocos2dx\lib\Cocos2dxBitmap.java

private static native void nativeInitBitmapDC(final int width,
            final int height, final byte[] pixels);

Thanks I appreciate the response. I think my biggest problem is trying to narrow down the correct path to call that function from then. this is what I have, I feel like some variation of it should work but things like proj.android need to be adjusted somehow because the “.” creates an error.

This is what I have, could you explain to me how to get the proper path?

cocos2dx_projects_game1_projandroid_app_src_org_cocos2dx_cpp_AppActivity_toCpp