【问题标题】:How to wait for a AdMob Rewarded Video to Load properly如何等待 AdMob 激励视频正确加载
【发布时间】:2018-06-08 09:50:08
【问题描述】:

我正在尝试在我的 Android 应用程序中使用 AdMob 奖励广告。 为了将其包含在推荐的应用程序中,我需要在用户单击按钮后等待奖励视频加载。 我在下面的代码中都在尝试它,但我得到了错误:

java.lang.IllegalStateException:必须在主 UI 上调用 showAd 线程。

当按钮被点击时:

b_r_ans.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        if(isSomBotaoLigado() && loaded[0])
            soundPool.play(soundID, MyApplication.getVolumeBotao(), MyApplication.getVolumeBotao(), 1, 0, 1f);

        Toast.makeText(MyApplication.getAppContext(),carregando_rv, Toast.LENGTH_LONG).show();




        Thread t_rv = new Thread(new Runnable() {
            public void run() {
                while(!rv_loaded){
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }


            }
        });
        t_rv.start();

        try {
            t_rv.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        mRewardedVideoAd.show();

    }
});

重写监听器:

@Override
    public void onRewardedVideoAdLoaded() {
        Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();
        rv_loaded = true;
    }

使用 mRewardedVideoAd.isLoaded() 函数会触发相同的问题。

如何等待视频正确加载?

【问题讨论】:

    标签: java android multithreading admob wait


    【解决方案1】:

    您似乎正在从另一个线程向 UI 调用 show,所以我会尝试像 force its execution on the main thread 一样:

    // Get a handler that can be used to post to the main thread
    Handler mainHandler = new Handler(Looper.getMainLooper());
    
    Runnable myRunnable = new Runnable() {
        @Override 
        public void run() {
             if (mRewardedVideoAd.isLoaded()) {
                 mRewardedVideoAd.show();
        }
    };
    mainHandler.post(myRunnable);
    

    【讨论】:

    • 在主线程中运行它会锁定应用程序。应用程序在最后中断。
    • 我已经编辑了答案,在展示广告之前添加了 isLoaded。也许它没有完全加载(即使它似乎是线程 t_rv 完成)
    • 还要检查线程是否正在结束,因此视频已加载,因为如果视频尚未完成加载,线程中的 while 将永远不会结束,您的应用程序将挂起
    【解决方案2】:

    您也可以在广告加载之前禁用该按钮,然后在 onRewardedVideoAdLoaded 函数中启用该按钮:

    override fun onRewardedVideoAdLoaded() {
            ad_btn.isEnabled = true
        }
    

    希望对您有所帮助。这是我正在使用的实现。

    【讨论】:

      【解决方案3】:

      通过这段代码解决了:

      @Override
          public void onRewardedVideoAdLoaded() {
              //Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();
              rv_loaded = true;
              if(goToAnswers)
                  mRewardedVideoAd.show();
      
              goToAnswers = false;
          }
      
      b_r_ans.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
      
                      if(isSomBotaoLigado() && loaded[0])
                          soundPool.play(soundID, MyApplication.getVolumeBotao(), MyApplication.getVolumeBotao(), 1, 0, 1f);
      
                      Toast.makeText(MyApplication.getAppContext(),carregando_rv, Toast.LENGTH_LONG).show();
      
                      if(mRewardedVideoAd.isLoaded())
                          mRewardedVideoAd.show();
                      else goToAnswers=true;
      
      
                  }
              });
      

      【讨论】:

        【解决方案4】:

        此代码将在加载奖励视频时显示ProgressDialog:

        package com.mountzoft.waitForrewardvideoProperly;
        
        import android.app.ProgressDialog;
        import android.content.Context;
        
        import com.google.android.gms.ads.AdRequest;
        import com.google.android.gms.ads.MobileAds;
        import com.google.android.gms.ads.reward.RewardItem;
        import com.google.android.gms.ads.reward.RewardedVideoAd;
        import com.google.android.gms.ads.reward.RewardedVideoAdListener;
        
        
        
        public class MainActivity extends AppCompatActivity implements RewardedVideoAdListener {
        
            private RewardedVideoAd mAd;
            private ProgressDialog mProgressDialog;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Please wait... Loading Reward Video Ad!");
                mProgressDialog.setCancelable(false);
            }
        
        
            private final showRewardVideoAd() {
                mProgressDialog.show();
                initializeRewardVideoAd();
                loadRewardedVideoAd();
            }
        
            private void initializeRewardVideoAd(){
                String adMobAppId = BuildConfig.AD_MOB_APP_ID; //id is stored in build gradle file
                MobileAds.initialize(this, adMobAppId);
                mAd = MobileAds.getRewardedVideoAdInstance(this);
                mAd.setRewardedVideoAdListener(this);
            }
        
            private void loadRewardedVideoAd() {
                String admobAdUnitId = BuildConfig.ADMOB_AD_UNIT_ID;//id is stored in build gradle
                mAd.loadAd(admobAdUnitId,
                        new AdRequest.Builder().build());
            }
        
            @Override
            public void onRewardedVideoAdLoaded() {
                mAd.show();
            }
        
            @Override
            public void onRewardedVideoAdOpened() {
                mAd = null;
            }
        
            @Override
            public void onRewardedVideoStarted() {
                mProgressDialog.dismiss();
            }
        
            @Override
            public void onRewardedVideoAdClosed() {
            }
        
            @Override
            public void onRewarded(RewardItem rewardItem) {
            }
        
        
            @Override
            public void onRewardedVideoAdLeftApplication() {
        
            }
        
            @Override
            public void onRewardedVideoAdFailedToLoad(int i) {
            }
        
            @Override
            public void onRewardedVideoCompleted(){
            }
        
        }
        

        【讨论】:

          【解决方案5】:

          如果您需要等到奖励广告加载,请使用 SingleLiveEvent。请参考以下代码sn-p。

          private val isRewardedAdLoaded: LiveData<Event<Boolean>>
              get() = _isRewardedAdLoaded
          
          private var _isRewardedAdLoaded: MutableLiveData<Event<Boolean>> = MutableLiveData()
          

          我在片段中使用了这个。所以这来自 onViewCreated()

          rewardedAd = createAndLoadRewardedAd()
          

          我将加载状态发布如下

          private fun createAndLoadRewardedAd(): RewardedAd {
              val rewarded = RewardedAd(requireContext(), getString(R.string.admob_rewarded_id_test))
              val adLoadCallback = object : RewardedAdLoadCallback() {
                  override fun onRewardedAdLoaded() {
                      Log.e(TAG, "onRewardedAdLoaded")
                      _isRewardedAdLoaded.postValue(Event(true))
                  }
          
                  override fun onRewardedAdFailedToLoad(errorCode: Int) {
                      _isRewardedAdLoaded.postValue(Event(false))
                  }
              }
              rewarded.loadAd(Builder().build(), adLoadCallback)
              return rewarded
          }
          

          这是奖励广告展示方法

          private fun showRewardedAds(rewarded: RewardedAd) {
              rewarded.show(requireActivity(), object : RewardedAdCallback() {
          
                  override fun onRewardedAdOpened() {
                      Log.e(TAG, "onRewardedAdOpened")
                  }
          
                  override fun onRewardedAdClosed() {
                      Log.e(TAG, "onRewardedAdClosed")
                      rewardedAd = createAndLoadRewardedAd()
                  }
          
                  override fun onUserEarnedReward(rewardItem: RewardItem) {
                      Log.e(TAG, "onUserEarnedReward")
                      translateText()
                  }
          
                  override fun onRewardedAdFailedToShow(errorCode: Int) {
                      translateText()
                  }
              })
          }
          

          最后我调用如下

          R.id.btnTranslate -> {
          
              if (rewardedAd.isLoaded){
                  showMessage(
                      getString(R.string.translate_ads_show_warning_title),
                      getString(R.string.translate_ads_show_warning_msg)
                  )
              } else {
                  progress.setVisible(true)
                  isRewardedAdLoaded.observe(viewLifecycleOwner, Observer {
                      it.getContentIfNotHandled()?.let { loaded ->
                          if (loaded and progress.isVisible){
                              progress.setVisible(false)
                              showMessage(
                                  getString(R.string.translate_ads_show_warning_title),
                                  getString(R.string.translate_ads_show_warning_msg)
                              )
                          }
                      }
                  })
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多