Java开发:如何实现Unity Ads展示出关闭按钮后按指定时长自动销毁广告
Unity Ads 广告展示后定时自动销毁实现方案
核心实现思路
- 精准锁定定时器触发起点
不要在广告刚拉起时就启动定时任务:Unity Ads插屏广告前几秒一般为强制不可跳过阶段,界面不会渲染关闭按钮,直接启动计时会导致逻辑偏差。需要通过SDK内置的展示生命周期回调,捕捉关闭按钮已完成渲染、用户可手动跳过的节点(对应旧版SDK的onUnityAdsShowSkippable回调),以此作为自动销毁计时的起点。 - 用全局调度器实现延迟关闭
将定时调度器声明为Activity的成员变量,避免每次触发广告都新建线程池导致的内存泄漏。计时到期后先校验广告当前仍处于展示状态,再调用SDK内置的广告隐藏方法主动关闭广告,效果和用户手动点击关闭按钮完全一致。 - 全流程清理定时任务
无论广告是被用户手动关闭、还是被定时器自动销毁,都需要在广告展示完成的回调中取消已启动的定时任务,避免后台线程常驻引发的泄漏问题。
对应代码改动示例
补充类成员变量
// 全局调度器(替代onClick里每次新建的临时调度器) private ScheduledExecutorService scheduler; // 自动销毁广告的延迟任务引用,用于后续取消 private ScheduledFuture<?> autoDestroyAdsTask; // 可配置的自动销毁等待时长,此处示例为2分钟 private final long AUTO_CLOSE_DELAY = TimeUnit.MINUTES.toMillis(2);
调整初始化逻辑
在onCreate方法中初始化全局调度器:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_1); // 初始化全局单线程调度器 scheduler = Executors.newSingleThreadScheduledExecutor(); String unity_id = Variable.getString(MainActivity.UNITY_ID, this, getString(R.string.unity_ads)); UnityAds.addListener(MainActivity1.this); UnityAds.initialize(this, unity_id); }
实现核心回调逻辑
当前Activity需要完整实现IUnityAdsShowListener接口的所有方法,核心回调逻辑如下:
// 广告到达可跳过节点(关闭按钮已渲染完成,此时启动计时) @Override public void onUnityAdsShowSkippable(String placementId) { // 先清理之前可能残留的定时任务,避免重复计时 if (autoDestroyAdsTask != null) { autoDestroyAdsTask.cancel(true); } // 启动自动销毁计时 autoDestroyAdsTask = scheduler.schedule(() -> { runOnUiThread(() -> { // 校验广告仍在展示状态,避免无效调用 if (UnityAds.isShowing()) { // 主动触发广告关闭,和用户手动点关闭按钮的行为一致 UnityAds.hide(placementId, IUnityAdsShowListener.SHOW_RESULT_COMPLETED); } }); }, AUTO_CLOSE_DELAY, TimeUnit.MILLISECONDS); } // 广告展示完成(无论手动/自动关闭都会触发) @Override public void onUnityAdsShowComplete(String placementId, IUnityAdsShowListener.ShowCompletionState state) { // 清理定时任务,避免内存泄漏 if (autoDestroyAdsTask != null) { autoDestroyAdsTask.cancel(true); autoDestroyAdsTask = null; } }
补充生命周期清理
在Activity销毁时统一释放资源:
@Override protected void onDestroy() { super.onDestroy(); // 关闭调度器,停止所有后台任务 if (scheduler != null && !scheduler.isShutdown()) { scheduler.shutdownNow(); } // 移除SDK监听,避免页面销毁后仍收到广告回调 UnityAds.removeListener(this); }
注意事项
- 自动销毁的等待时长可自由配置,需实现X分钟自动销毁时,直接修改
AUTO_CLOSE_DELAY的参数为TimeUnit.MINUTES.toMillis(X)即可 - 坚决不要沿用原代码中在
onClick里每次新建ScheduledExecutorService的写法,这种写法会导致每次触发广告都新增独立线程池,就算Activity销毁线程也不会停止,极易引发内存泄漏 - 执行关闭操作前一定要加
UnityAds.isShowing()的状态校验,避免广告已经被用户关闭后再调用关闭方法触发SDK空指针异常 - 不要在广告强制不可跳过阶段启动计时,不然会出现「还没弹出关闭按钮,广告就提前关闭」的异常用户体验
内容的提问来源于stack exchange,提问作者Harle
相关产品推荐
相关产品推荐

