Admob Interstitial и error isLoaded должны вызываться в основном потоке пользовательского интерфейса

после того, как пользователь William предложит мне изменить свой код для показа интерстициального объявления на это

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

и для показа объявлений это:

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;

}

на каждом gameover в игре я получаю эту ошибку:

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)

что здесь не так? Пожалуйста, объясните мне просто, как это возможно, потому что я новичок без каких-либо знаний программирования раньше :) спасибо!

2 ответов


это, возможно, не полный ответ, но его трудно сказать правильный ответ, потому что его не ясно из вашего кода выше. Вы не показали, где вы используете GameOver (), но я думаю, что вы назвали его в неправильном месте, я думаю, вы называете его в любом фоновом потоке, потому что внутри GameOver вы вызываете interstitial.isLoaded() что вызывает вашу проблему. Как сказал stacktrace, вызовите его в основном потоке пользовательского интерфейса. Для exqample вызовите это внутри GameOver ():

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

Возможно, вам придется позвонить с ссылка на действие, это зависит от того, откуда вы вызываете GameOver ():

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

поделитесь моим случаем и решением.

Я сделал новый поток и вызов isLoaded (). Он получил ту же ошибку. Так что я решаю его ниже кода с помощью Messager.

надеюсь, что это поможет.

код, как показано ниже.

основные темы:

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


            }
        };

}

другой поток

    public void run(){

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