我正在编写代码,将 Applovins 的 MaxNative 广告加载到 recyclerView 中。我第一次加载它并将其用于每个新呼叫。这是代码
fun showNativeAd2(adContainer: FrameLayout) {
val params = adContainer.layoutParams
params.height = 300.px
adContainer.layoutParams = params
if (isPremium()) {
adContainer.visibility = View.GONE
return
}
adContainer.visibility = View.VISIBLE
val nativeAdLoader = MaxNativeAdLoader(adMobIds.nativeId, adContainer.context)
nativeAdLoader.setNativeAdListener(object : MaxNativeAdListener() {
override fun onNativeAdLoaded(nativeAdView: MaxNativeAdView?, ad: MaxAd) {
// Clean up any pre-existing native ad to prevent memory leaks.
if (nativeAd != null) {
nativeAdLoader.destroy(nativeAd)
}
nativeAd = ad
globalNativeAd = nativeAdView
adContainer.removeAllViews()
adContainer.addView(nativeAdView)
}
override fun onNativeAdLoadFailed(adUnitId: String, error: MaxError) {
// We recommend retrying with exponentially higher delays up to a maximum delay
log("$adUnitId $error")
}
override fun onNativeAdClicked(ad: MaxAd) {
log("$ad")
}
})
if (globalNativeAd == null)
nativeAdLoader.loadAd()
else{
adContainer.removeAllViews()
adContainer.addView(globalNativeAd)
}
}
这里的 globalNative 是全局变量,如果 globalNative 为 null,它只会在第一次调用函数时初始化,并且对于每个新调用,它只显示存储在 globalNative 变量中的内容。但是在加载时,recyclerview 显示错误。
这里是堆栈跟踪。
2023-04-27 12:15:29.952 10265-10265/com.thesrb.bluewords E/CustomActivityOnCrash: The previous app process crashed. This is the stack trace of the crash:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:5269)
at android.view.ViewGroup.addView(ViewGroup.java:5090)
at android.view.ViewGroup.addView(ViewGroup.java:5030)
at android.view.ViewGroup.addView(ViewGroup.java:5003)
at com.thesrb.bluewords.ads_libs.AppLovinUtils.showNativeAd2(AppLovinUtils.kt:161)
at com.thesrb.bluewords.adapter.WordAdapter.setAds(WordAdapter.kt:217)
at com.thesrb.bluewords.adapter.WordAdapter.onBindViewHolder(WordAdapter.kt:188)
at com.thesrb.bluewords.adapter.WordAdapter.onBindViewHolder(WordAdapter.kt:32)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7254)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
我创建了一个扩展函数(在 kotlin 中)来避免此类崩溃,它对我来说非常有效。
将此功能添加到任何文件或
Object
类型类
fun ViewGroup.addCleanView(view: View?) {
(view?.parent as? ViewGroup)?.removeView(view)
this.removeAllViews()
this.addView(view)
}
现在,用法很简单如下:
adContainer.addCleanView(globalNativeAd)
这里也是,
adContainer.addCleanView(nativeAdView)
无需删除视图等。我的扩展功能将处理所有问题。