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

会有一股神秘感。 提交于 2019-11-27 07:42:15

问题


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!


回答1:


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();
         }
        }
    });



回答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();
                   }
        }


来源:https://stackoverflow.com/questions/28501787/admob-interstitial-and-error-isloaded-must-be-called-on-the-main-ui-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!