android InterstitialAd即使在加载后仍返回空值

sf6xfgos  于 2022-11-20  发布在  Android
关注(0)|答案(1)|浏览(106)

我已经在Activity开始时加载了插播广告,但是当我显示它时,它返回了一个空值。Log。

2022-11-18 09:53:45.102 18604-18604/com.blogspot.bunnylists.maate D/ADAD: Ad was loaded.
2022-11-18 09:54:17.358 18604-18604/com.blogspot.bunnylists.maate D/ADAD: The interstitial wasn't loaded yet.

这个应用程序是一个单活动应用程序。我按照官方文档实现了一个插播广告。所有与广告相关的代码都在MainActivity中。单击一个按钮后,我在MainActivityLayout上显示了一个全屏片段。我在该片段中实现了一个ReycerView。当recycerView在屏幕上加载了一些视图时,然后我想显示Ad。我在onBindViewHolder方法内调用MainActivity类的showAd()方法。

class MainActivity : AppCompatActivity() {
    private lateinit var bind : ActivityMainBinding
    private lateinit var viewModel: MainActivityViewModel
    private var mInterstitialAd: InterstitialAd? = null
    val TAG = "ADAD"
    val adRequest = AdRequest.Builder().build()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bind = DataBindingUtil.setContentView(this, com.blogspot.bunnylists.maate.R.layout.activity_main)
        val repository = (application as MyApplication).repository
        viewModel = ViewModelProvider(this, MyViewModelFactory(repository, "MainActivity"))[MainActivity2ViewModel::class.java]

        //Here I am loading the Ad at the creation of the MainActivity
        loadAd()

        mInterstitialAd?.fullScreenContentCallback = object: FullScreenContentCallback() {
            override fun onAdClicked() {
                // Called when a click is recorded for an ad.
                Log.d(TAG, "Ad was clicked.")
            }

            override fun onAdDismissedFullScreenContent() {
                // Called when ad is dismissed.
                Log.d(TAG, "Ad dismissed fullscreen content.")
                mInterstitialAd = null
            }

            override fun onAdFailedToShowFullScreenContent(p0: AdError) {
                // Called when ad fails to show.
                Log.e(TAG, "Ad failed to show fullscreen content.")
                mInterstitialAd = null
            }

            override fun onAdImpression() {
                // Called when an impression is recorded for an ad.
                Log.d(TAG, "Ad recorded an impression.")
            }

            override fun onAdShowedFullScreenContent() {
                // Called when ad is shown.
                Log.d(TAG, "Ad showed fullscreen content.")
            }
        }

    }

   // The method which is called from the onBindViewHolder
    fun showAd() {
        if (mInterstitialAd != null) {
            Log.d(TAG, "showing Ad")
            mInterstitialAd?.show(this)
            loadAd()
        } else {
            Log.d(TAG, "The interstitial wasn't loaded yet.")
        }
    }

    private fun loadAd(){
        InterstitialAd.load(this,
            "ca-app-pub-3940256099942544/1033173712",
            adRequest,
            object : InterstitialAdLoadCallback() {
                override fun onAdFailedToLoad(adError: LoadAdError) {
                    Log.d(TAG, adError.toString())
                    mInterstitialAd = null
                }

                override fun onAdLoaded(interstitialAd: InterstitialAd) {
                    Log.d(TAG, "Ad was loaded.")
                    mInterstitialAd = interstitialAd
                }
            })
    }
}

绑定视图持有者:

override fun onBindViewHolder(holder: MyViewHolder, position: Int){
    if(position%20==0){
       MainActivity().showAd()
    }
}
ygya80vv

ygya80vv1#

切勿执行此操作:

MainActivity()

上面是通过调用Activity的构造函数来示例化Activity。这有两个问题:
1.它与您使用的示例不同,因此它尚未与您的广告一起设置。
1.如果它不是由操作系统创建的,那么它就没有被正确设置。它充满了不应该为null的null对象,所以很容易导致崩溃。它也很荒谬,因为你没有把它用作Activity--没有办法把你自己创建的Activity示例放到屏幕上。
您需要从适配器公开一个广告显示回调函数,并调用它:

class MyAdapter: RecyclerView.Adapter<SomeType, SomeViewHolder>() {

    var onRequestAd: (()->Unit)? = null

    override fun onBindViewHolder(holder: MyViewHolder, position: Int){
        if(position%20==0){
           onRequestAd?.invoke()
        }
        //...
    }
}

然后在Activity中,在创建适配器示例之后,应立即将侦听器设置为调用showAd()

val adapter = MyAdapter()
adapter.onRequestAd = ::showAd // or { showAd() }
bind.adapter = adapter

我在你的评论中提到的单独的问题。在这一行:

mInterstitialAd?.fullScreenContentCallback = object: FullScreenContentCallback() {

你调用的时候mInterstitialAd仍然是null,所以它什么都不做,你的回调函数也不会被使用。你需要把这段代码移到onAdLoaded回调函数里面,这样它就可以在广告创建之后被添加到广告中,这样每次你加载新广告时它都会被添加。
顺便说一句,你可能需要一个更复杂的方法来决定何时显示广告。事实上,我认为如果第20个项目刚刚离开屏幕,用户上下摇动它,它会不断地请求广告。你可能需要添加一个计时器,例如:

private var lastAdTime = 0L

override fun onBindViewHolder(holder: MyViewHolder, position: Int){
    if(position%20==0 && lastAdTime + 3000 < System.currentTimeMillis()){
       onRequestAd()
       lastAdTime = System.currentTimeMillis()
    }
}

相关问题