AdMob Interstitial y error isLoaded deben ser llamados en el subproceso principal de la interfaz de usuario

Después de que el usuario William me sugiera cambiar mi código para mostrar el anuncio intersticial a este

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

Y para mostrar este anuncio:

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

En cada gameover en juego consigo este 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.be(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) 

¿Qué está mal aquí? Por favor, explíqueme simple como sea posible, porque yo `m novato sin ningún conocimiento de programación antes 🙂 Gracias!

Esta quizás no es la respuesta completa, pero es difícil decir la respuesta correcta porque no está claro en su código anterior. No has mostrado dónde usas GameOver (), pero creo que lo llamaste en el lugar equivocado, creo que lo llamas en cualquier hilo de fondo, porque dentro de GameOver llamas a interstitial.isLoaded() que causa tu problema. Como el stacktrace dijo, llámalo en el hilo principal de ui. Por ejemplo, llame a esto dentro de su GameOver ():

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

Posiblemente tienes que llamar con una referencia de actividad, depende de donde llamas a GameOver ():

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

Compartir mi caso y solución.

Hice el nuevo hilo y llamo isLoaded (). Recibió el mismo error. De modo que lo resuelvo por debajo del código usando Messager.

Espero que esto ayude.

Código como se indica a continuación.

Hilo principal:

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

Otros hilos

  public void run(){ while(true){ Message message; // ------ For AdMob ------ Message message = mHandler.obtainMessage(ACTION_ADMOB_IS_LOADED,null); message.sendToTarget(); } } 
  • No se puede resolver ContextCompat en Android
  • Utilizar ADB para capturar la pantalla
  • Diferencia entre el conmutador empaquetado y el interruptor escaso dalvik opcode
  • No se puede crear el controlador dentro de hilo que no ha llamado Looper.prepare () dentro de AsyncTask para ProgressDialog
  • Los puntos de interrupción del método pueden reducir drásticamente la depuración
  • ¿Por qué resolveInfo.loadLabel () es tan ridículamente lento?
  • Cómo guardar / guardar objetos de clase personalizados en Android?
  • Dispositivos Android conectados con NSD, cómo enviar mensajes utilizando sockets (Client-Client)?
  • Ejecutar un jar ejecutable en android
  • ¿Es la mejor práctica para almacenar y usar un token OAuth2 en Android?
  • Parallax XY y cálculo de la rotación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.