Karnak
Karnak

Reputation: 113

AdMob Interstitial and error isLoaded must be called on the main UI thread

After user William suggest me to change my code for showing interstitial ad to this

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    //setDebugMode(true);
    initialiseAccelerometer();

    interstitial = new InterstitialAd(this);
    interstitial.setAdUnitId(getResources().getString(R.string.InterstitialAd_unit_id));

    interstitial.setAdListener(new AdListener() {
        public void onAdClosed() {
            // Create another ad request.
            final AdRequest adRequest = new AdRequest.Builder()
                .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                .build();
            interstitial.loadAd(adRequest);
        }
    });
    // Create ad request.
    final AdRequest adRequest = new AdRequest.Builder()
            .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
            .build();
    interstitial.loadAd(adRequest);
}

and for showing ad this:

public synchronized void GameOver() {
    if (lives_left > 0) {
        //success! - game passed - save score
        ScoreManager.save_localscore_simple(score_times[currentLevel], "" + currentLevel, false);

        if (Level_Buttons.length >= currentLevel + 1)
            ScoreManager.save_localscore_simple(unlocked, "unlock" + (currentLevel + 1));

        if (sound_success != 0 && !sound_muted)
            sp.play(sound_success, 1, 1, 0, 0, 1);

        //open interstitial ad
        if (interstitial.isLoaded()) {
            interstitial.show();
        }


    } else {
        //game not passed
        if (sound_gameover != 0 && !sound_muted)
            sp.play(sound_gameover, 1, 1, 0, 0, 1);
    }


    //open interstitial ad
    if (interstitial.isLoaded()) {
        interstitial.show();
    }

    StopMusic();
    state = GAMEOVER;

}

On every gameover in game I get this error:

W/dalvikvm(20469): threadid=11: thread exiting with uncaught exception      (group=0x4180bda0)
E/AndroidRuntime(20469): FATAL EXCEPTION: Thread-67543
E/AndroidRuntime(20469): Process: com.test.mygame, PID: 20469
E/AndroidRuntime(20469): java.lang.IllegalStateException: isLoaded must be      called on the main UI thread.
E/AndroidRuntime(20469):    at     com.google.android.gms.common.internal.bh.b(SourceFile:251)
E/AndroidRuntime(20469):    at  com.google.android.gms.ads.internal.b.e(SourceFile:345)
E/AndroidRuntime(20469):    at com.google.android.gms.ads.internal.client.m.onTransact(SourceFile:66)
E/AndroidRuntime(20469):    at android.os.Binder.transact(Binder.java:361)
E/AndroidRuntime(20469):    at com.google.android.gms.internal.ap$a$a.isReady(Unknown Source)
E/AndroidRuntime(20469):    at com.google.android.gms.internal.au.isLoaded(Unknown Source)
E/AndroidRuntime(20469):    at com.google.android.gms.ads.InterstitialAd.isLoaded(Unknown Source)
E/AndroidRuntime(20469):    at com.test.mygame.MainGame.GameOver(MainGame.java:1128)
E/AndroidRuntime(20469):    at com.test.mygame.MainGame.Step(MainGame.java:773)
E/AndroidRuntime(20469):    at com.test.nudge.Screen.run(Screen.java:207)
E/AndroidRuntime(20469):    at java.lang.Thread.run(Thread.java:841)

What is wrong here? Please explain me simple as possible because I`m newbie without any programming knowledge before :) Thanks!

Upvotes: 11

Views: 11224

Answers (2)

Share my case and solution.

I did new thread and call isLoaded(). It got this same error. So that I solve it by below code using Messager.

Hope this help.

Code as below.

Main thread:

public void onCreate() {

        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message message) {
                switch (message.what) {
                    case ACTION_ADMOB_IS_LOADED:
                        MainActivity.logForDebug(TAG,"AdMob : Check for loaded");
                        if(mIAds.isLoaded()) {
                            MainActivity.logForDebug(TAG,"AdMob : Loaded ...... OK");
                            mIAds.show();
                        }
                        break;
                }


            }
        };

}

Other thread

    public void run(){

        while(true){
                Message message;
                // ------  For AdMob ------
                Message message = mHandler.obtainMessage(ACTION_ADMOB_IS_LOADED,null);
                message.sendToTarget();
                   }
        }

Upvotes: 1

Opiatefuchs
Opiatefuchs

Reputation: 9870

This is maybe not the full answer, but It´s hard to say the right answer because it´s not clear from Your code above. You´ve not showed where You use GameOver(), but I think You called it in the wrong place, I think You call it in any background thread because inside GameOver You call interstitial.isLoaded() which causing Your problem. Like the stacktrace said, call it in the main ui thread. For exqample, call this inside Your GameOver():

   runOnUiThread(new Runnable() {
        @Override public void run() {
            if (interstitial.isLoaded()) {
              interstitial.show();
         }
        }
    });

Possibly You have to call it with an activity reference, it depends from where Do You call GameOver():

    mYourActivity.runOnUiThread(new Runnable() {
        @Override public void run() {
            if (interstitial.isLoaded()) {
              interstitial.show();
         }
        }
    });

Upvotes: 25

Related Questions