Android NDK JNI w/ Admob

I’m trying to use C++ to call a Java method I made called void showAd() that loads a banner ad from Admob (adView.loadAd(adRequest)). The showAd() method is in the SDLActivity class in SDLActivity.java and the adView and adRequest are public SDLActivity class level variables.

In onCreate() I initialize mobile ads, create new AdView(context: this), set banner type, set test ID, build an AdRequest, and add the adView the view hierarchy so it’s visible.

My C++ code calls the Java function perfectly using JNI. I know this because if I remove adView.load(adRequest) from showAd() and replace with generic output like Log.v(“test”) it outputs to LogCat percetly and returns the execution flow back to the C++ program.

If I simply move adView.load(adRequest) to the OnCreate() method, it works fine, however I lose the ability to control the adView through C++ (reloading, hiding, showing, etc.)

I’ve tried static and non-static versions of the adView, adRequest variables and showAd() method with no success.

Any guidance is appreciated. Below is some code:

SDLActivity.java
public class SDLActivity extends Activity
{

protected void onCreate(Bundle savedInstanceState)
{

public AdRequest adRequest;

MobileAds.initialize(this, “ca-app-pub-3940256099942544~3347511713”);
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(“ca-app-pub-3940256099942544/6300978111”);
adRequest = new AdRequest.Builder().build();
mLayout.addView( adView );

} // end onCreate()

public void showAd() {
    adView.loadAd( adRequest );
}

} // end SDLActivity class

C++ using SDL & JNI to call Java method (works perfectly):
{
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
jobject activity = (jobject)SDL_AndroidGetActivity();
jclass clazz(env->GetObjectClass(activity));
jmethodID method_id = env->GetMethodID(clazz, “showAd”, “()V”);
env->CallVoidMethod(activity, method_id);
}

Whoops the “public AdRequest adRequest;” is not in onCreate(), it’s a level above under SDLActivity class.

You should be putting your methods in an overrided class, no need to modify SDLActivity.

Your C++ call will be on the wrong thread, which is why the ads aren’t working. You’ll need to use a callback so it will run on the proper thread. SDL2 has already set this up and you can piggy-back your custom callbacks in your overrided class.

I can paste a rough example here if you need further help.

Thanks for the quick reply and I had the same idea, but struggled with implementation. Like a Button created in OnCreate with an onClick() overrided call back method, but then how would I have C++ trigger the onClick() callback without actually touching the button?

Any rough code would be helpful thanks!

I have all you need. write me e-mail

Don’t know where to find your email – I’m jared.salina@gmail.com

Hey Ant, no idea what your email is, but if you could email me or just paste the code in this chat I would greatly appreciate it as I’m stuck! Thanks.

1 Like

Hi There
I would be grateful for help on this - as I have a similar issue for full screen ads.
Thks!

Send me your email and I’ll send you my code

1 Like

I’m also having a similar issue for video ads and toast. If there are any code examples that would help out.
Thanks!

please send the code. My email address is vivtofreeto@gmail.com. Thank you for your help!

Sorry for the lack of response guys - I got super busy. If you’re still stuck, here’s some code that will help.

In your public class MainActivity extends SDLActivity { you should have something like this:

public static void showAd() {
    sendMessage(COMMAND_SHOWAD, 0);
}

static final int COMMAND_SHOWAD = COMMAND_USER + 0;
@Override
protected boolean onUnhandledMessage(int command, Object param) {
    switch (command) {
        case COMMAND_SHOWAD:
            if(mInterstitialAd.isLoaded())
                mInterstitialAd.show();
            return true;
    }
    return false;
}

Then, in your C / C++ code you should set up the JNI environment so you can make calls into Java:

#include <jni.h>

jclass cl = nullptr;
jmethodID showAd = nullptr;

JNIEnv *env = (JNIEnv*)SDL_AndroidGetJNIEnv();
if(env) {
	jobject activity = (jobject)SDL_AndroidGetActivity();
	if(activity)
		cl = env->GetObjectClass(activity);
	env->DeleteLocalRef(activity);
}

and then when you’re ready to show an ad:

if(cl) {
	if(!showAd)
		showAd = env->GetStaticMethodID(cl, "showAd", "()V");
	if(showAd)
		env->CallStaticVoidMethod(cl, showAd);
}

Clear as mud? Try to break it down by understanding how to use JNI. And the reason we call sendMessage is so that the main thread picks up the message because ads will only work in the main thread.