创建控制器前,请先完成 CloudX 和 Google Mobile Ads 初始化。控制器外部仍应保留您现有的频控、重试和广告位触发时机规则。
FirstLookInterstitialController.kt
import android.app.Activity
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import io.cloudx.sdk.CloudX
import io.cloudx.sdk.CloudXAd
import io.cloudx.sdk.CloudXError
import io.cloudx.sdk.CloudXInterstitialAd
import io.cloudx.sdk.CloudXInterstitialListener
class FirstLookInterstitialController(
private val activity: Activity,
private val cloudXAdUnitId: String,
private val adMobAdUnitId: String,
) {
enum class Source {
CLOUDX,
ADMOB,
}
interface Listener {
fun onAdLoaded(source: Source) {}
fun onAdLoadFailed(source: Source, message: String?) {}
fun onAdShown(source: Source) {}
fun onAdShowFailed(source: Source, message: String?) {}
fun onAdClosed(source: Source) {}
fun onAdClicked(source: Source) {}
}
var listener: Listener? = null
private val cloudXInterstitial: CloudXInterstitialAd =
CloudX.createInterstitial(activity, cloudXAdUnitId)
private var adMobInterstitial: InterstitialAd? = null
private var isLoadingCloudX = false
private var isLoadingAdMob = false
init {
cloudXInterstitial.listener = createCloudXListener()
}
fun load() {
if (isLoadingCloudX || isLoadingAdMob || cloudXInterstitial.isAdReady || adMobInterstitial != null) {
return
}
isLoadingCloudX = true
cloudXInterstitial.load()
}
fun show(): Boolean {
if (cloudXInterstitial.isAdReady) {
cloudXInterstitial.show(activity)
return true
}
return showAdMobFallback()
}
fun destroy() {
cloudXInterstitial.destroy()
adMobInterstitial = null
listener = null
}
private fun createCloudXListener() = object : CloudXInterstitialListener {
override fun onAdLoaded(cloudXAd: CloudXAd) {
isLoadingCloudX = false
listener?.onAdLoaded(Source.CLOUDX)
}
override fun onAdLoadFailed(adUnitId: String, cloudXError: CloudXError) {
isLoadingCloudX = false
loadAdMobFallback()
}
override fun onAdDisplayed(cloudXAd: CloudXAd) {
listener?.onAdShown(Source.CLOUDX)
}
override fun onAdDisplayFailed(cloudXAd: CloudXAd, cloudXError: CloudXError) {
if (showAdMobFallback()) {
return
}
listener?.onAdShowFailed(Source.CLOUDX, cloudXError.message)
}
override fun onAdHidden(cloudXAd: CloudXAd) {
listener?.onAdClosed(Source.CLOUDX)
}
override fun onAdClicked(cloudXAd: CloudXAd) {
listener?.onAdClicked(Source.CLOUDX)
}
}
private fun loadAdMobFallback() {
if (isLoadingAdMob || adMobInterstitial != null) {
return
}
isLoadingAdMob = true
InterstitialAd.load(
activity,
adMobAdUnitId,
AdRequest.Builder().build(),
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(interstitialAd: InterstitialAd) {
isLoadingAdMob = false
adMobInterstitial = interstitialAd.apply {
fullScreenContentCallback = createAdMobFullScreenCallback()
}
listener?.onAdLoaded(Source.ADMOB)
}
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAdMob = false
adMobInterstitial = null
listener?.onAdLoadFailed(Source.ADMOB, loadAdError.message)
}
},
)
}
private fun showAdMobFallback(): Boolean {
val ad = adMobInterstitial ?: return false
ad.show(activity)
return true
}
private fun createAdMobFullScreenCallback() = object : FullScreenContentCallback() {
override fun onAdShowedFullScreenContent() {
adMobInterstitial = null
listener?.onAdShown(Source.ADMOB)
}
override fun onAdDismissedFullScreenContent() {
adMobInterstitial = null
listener?.onAdClosed(Source.ADMOB)
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
adMobInterstitial = null
listener?.onAdShowFailed(Source.ADMOB, adError.message)
}
override fun onAdClicked() {
listener?.onAdClicked(Source.ADMOB)
}
}
}
show()。如果返回 false,表示 CloudX 和回退广告都没有准备好,此时应继续应用流程,不展示广告。
if (!firstLookInterstitial.show()) {
continueToNextScreen()
}
load()。
此示例采用懒加载回退:只有 CloudX 加载失败后才加载 AdMob。除非 CloudX 针对您的应用建议其他上线策略,否则不要并行加载两个来源。