Thank you for your help!
In my real project I was actually extending the SDLActivity class and using “runOnUiThread” for these calls. However, I did not know about SDL_SendAndroidMessage, which does seem more convenient.
I tried your suggested style, but unfortunately, I’m still getting the same result. Here is a new sample project:
Java:
package org.libsdl.app;
import android.util.Log;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.RequestConfiguration;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.AdRequest;
import androidx.annotation.NonNull;
public class MainActivity extends SDLActivity {
private boolean admobInitCalled = false ;
private boolean admobInitialized = false ;
private boolean admobAdRequested = false ;
private RewardedAd mRewardedAd ;
private String ADMOB_LOG_TAG = "admobTest";
public void admobInit()
{
Log.d(ADMOB_LOG_TAG,"calling MobileAds.initialize" );
admobInitCalled = true ;
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
admobInitialized = true;
RequestConfiguration requestConfiguration = new RequestConfiguration.Builder().build();
MobileAds.setRequestConfiguration(requestConfiguration);
Log.d(ADMOB_LOG_TAG,"onInitializationComplete" );
}
});
}
public void admobLoadAd()
{
if ( !admobInitialized ) {
return ;
}
if ( admobAdRequested ) {
return ; // already loading
}
admobAdRequested = true ;
Log.d(ADMOB_LOG_TAG,"calling RewardedAd.load" );
AdRequest adRequest = new AdRequest.Builder().build();
RewardedAd.load(this,
"ca-app-pub-3940256099942544/5224354917", // Test
adRequest, new RewardedAdLoadCallback() {
@Override
public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
// Ad successfully loaded.
mRewardedAd = rewardedAd ;
admobAdRequested = false ;
Log.d(ADMOB_LOG_TAG,"onAdLoaded" );
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
// Ad failed to load.
mRewardedAd = null ;
admobAdRequested = false ;
Log.d(ADMOB_LOG_TAG,"onAdFailedToLoad" );
}
});
}
public void admobShowAd()
{
if ( !admobInitialized ) {
return ;
}
if ( mRewardedAd != null ) {
mRewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
@Override
public void onAdClicked() {
// Called when a click is recorded for an ad.
Log.d(ADMOB_LOG_TAG,"onAdClicked" );
}
@Override
public void onAdDismissedFullScreenContent() {
// Called when ad is dismissed.
// Set the ad reference to null so you don't show the ad a second time.
Log.d(ADMOB_LOG_TAG,"onAdDismissedFullScreenContent" );
mRewardedAd = null;
}
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
// Called when ad fails to show.
Log.d(ADMOB_LOG_TAG,"onAdFailedToShowFullScreenContent" );
mRewardedAd = null;
}
@Override
public void onAdImpression() {
// Called when an impression is recorded for an ad.
Log.d(ADMOB_LOG_TAG,"onAdImpression" );
}
@Override
public void onAdShowedFullScreenContent() {
// Called when ad is shown.
Log.d(ADMOB_LOG_TAG,"onAdShowedFullScreenContent" );
}
});
mRewardedAd.show(this, new OnUserEarnedRewardListener() {
@Override
public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
// Handle the reward.
Log.d(ADMOB_LOG_TAG,"onUserEarnedReward" );
}
});
}
}
static final int COMMAND_REWARDEDTESTTOUCH = COMMAND_USER + 1;
@Override protected boolean onUnhandledMessage(int command, Object param)
{
if ( command == COMMAND_REWARDEDTESTTOUCH ) {
if (!admobInitCalled) {
admobInit();
} else {
if (mRewardedAd == null && !admobAdRequested) {
admobLoadAd();
} else if (mRewardedAd != null) {
admobShowAd();
}
}
return true ;
}
return false ;
}
}
C code:
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
const Uint32 COMMAND_USER = 0x8000;
const Uint32 COMMAND_REWARDEDTESTTOUCH = COMMAND_USER + 1;
int main(int argc, char *argv[]) {
if (!SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init failed (%s)", SDL_GetError());
return 1;
}
// Create a window
SDL_Window* window = SDL_CreateWindow("testadmob", 320, 200, SDL_WINDOW_MAXIMIZED);
if (!window) {
SDL_Log("Unable to create window: %s", SDL_GetError());
SDL_Quit();
return 1;
}
// Main loop flag
bool running = true;
// Main event loop
while (running) {
SDL_Event event;
// Poll and process events
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT: // Handle quit events
running = false;
break;
case SDL_EVENT_FINGER_DOWN:
SDL_SendAndroidMessage(COMMAND_REWARDEDTESTTOUCH, 0);
break ;
default:
// Handle other events
break;
}
}
}
// Cleanup and shutdown
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I recorded a little test clip, this is from the code above being run. Each tap cycles through the adview cycle. I do one ad that works normally, and then on the second ad I go to the home screen and back - which creates the wonkyness. (This is just a test app, so the screen is all black regardless, but you can see it still says “Test Ad” after coming back from the home screen, and it no longer responds to my touches to load further ads - showing that the app has not gotten back control completely/or the Ad view is still in front).