Unity中检查激励广告可用性及解决重复打印日志问题
解决AdMob激励广告持续打印"Dummy IsLoaded"日志的优化方案
你遇到的这个日志刷屏问题,核心原因是高频重复调用广告加载检查和请求方法——如果你的IsAdAvailable()被每帧(比如Update里)或者高频触发,每次检测到未加载就立即发起请求,AdMob测试SDK会返回Dummy广告对象,反复触发IsLoaded()的日志输出。下面给你几个更合理的优化方案:
方案一:添加请求节流,避免重复发起广告请求
首先在你的AdmobController里加一个状态标记,防止短时间内重复请求广告,同时修改检查逻辑:
1. 改造AdmobController
public class AdmobController : MonoBehaviour { // 原有变量... private bool _isRequestingAd = false; // 新增:标记是否正在请求广告 public void RequestRewardBasedVideo() { // 如果正在请求广告,直接返回,避免重复请求 if (_isRequestingAd) return; _isRequestingAd = true; #if UNITY_ANDROID string adUnitId = "ca-app-pub-3940256099942544/5224354917"; #elif UNITY_IPHONE string adUnitId = "ca-app-pub-3940256099942544/1712485313"; #else string adUnitId = "unexpected_platform"; #endif AdRequest request = new AdRequest.Builder().Build(); this.rewardBasedVideo.LoadAd(request, adUnitId); } // 在广告加载完成的回调里重置请求标记 public void HandleRewardBasedVideoLoaded(object sender, EventArgs args) { _isRequestingAd = false; // 原有回调逻辑... } // 在广告加载失败时也要重置标记,避免永久锁死请求 public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args) { _isRequestingAd = false; // 可选:添加延迟重试逻辑,比如5秒后重新请求 Invoke(nameof(RequestRewardBasedVideo), 5f); // 原有回调逻辑... } }
2. 修改IsAdAvailable()检查逻辑
private bool IsAdAvailable() { if (AdmobController.instance.rewardBasedVideo == null) return false; bool isLoaded = AdmobController.instance.rewardBasedVideo.IsLoaded(); // 只有广告未加载且没有在请求时,才发起新请求 if (!isLoaded && !AdmobController.instance._isRequestingAd) { AdmobController.instance.RequestRewardBasedVideo(); } return isLoaded; }
方案二:改用回调驱动,彻底抛弃轮询(更优)
最好的做法是不要主动轮询广告状态,而是利用AdMob的回调事件来被动更新广告可用状态,完全避免频繁调用IsLoaded():
1. 改造AdmobController,添加状态事件
public class AdmobController : MonoBehaviour { // 原有变量... public event Action<bool> OnAdAvailabilityChanged; // 广告可用状态变化事件 private bool _isAdAvailable = false; void Start() { rewardBasedVideo = RewardBasedVideoAd.Instance; // 绑定关键回调 rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded; rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad; rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed; // 首次请求广告 RequestRewardBasedVideo(); } private void HandleRewardBasedVideoLoaded(object sender, EventArgs args) { _isAdAvailable = true; OnAdAvailabilityChanged?.Invoke(true); // 通知外部广告已就绪 } private void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args) { _isAdAvailable = false; OnAdAvailabilityChanged?.Invoke(false); // 通知外部广告加载失败 Invoke(nameof(RequestRewardBasedVideo), 5f); // 延迟重试 } private void HandleRewardBasedVideoClosed(object sender, EventArgs args) { _isAdAvailable = false; OnAdAvailabilityChanged?.Invoke(false); // 通知外部广告已关闭 RequestRewardBasedVideo(); // 自动请求下一个广告 } // 公开获取当前广告状态的方法 public bool IsAdAvailable() { return _isAdAvailable && rewardBasedVideo != null; } }
2. 改造按钮脚本,通过事件响应状态变化
public class RewardedAdButton : MonoBehaviour { private Button _adButton; void Start() { _adButton = GetComponent<Button>(); // 初始化按钮状态 _adButton.interactable = AdmobController.instance.IsAdAvailable(); // 订阅广告状态变化事件 AdmobController.instance.OnAdAvailabilityChanged += UpdateButtonState; } private void UpdateButtonState(bool isAvailable) { _adButton.interactable = isAvailable; } public void ShowRewardedAds() { if (AdmobController.instance.IsAdAvailable()) { AdmobController.instance.rewardBasedVideo.Show(); } else { Debug.Log("Reward based video ad is not ready yet"); } } // 销毁时取消订阅,避免内存泄漏 void OnDestroy() { AdmobController.instance.OnAdAvailabilityChanged -= UpdateButtonState; } }
问题根源说明
你使用的是AdMob测试广告ID,当你频繁调用LoadAd()和IsLoaded()时,AdMob测试SDK会返回一个"Dummy"广告对象,每次调用IsLoaded()都会打印这个日志。如果你的IsAdAvailable()是在Update里被调用的,就会每帧触发一次,导致日志刷屏。
内容的提问来源于stack exchange,提问作者Holy semicolon
相关产品推荐
相关产品推荐

