🎯 广告类型
版本 GroMore

📺 插屏广告

插屏广告(全屏视频/插页)建议采用“先缓存、后展示”的流程。

1. 基本流程

import 'package:gromore_ads/gromore_ads.dart';

class InterstitialController {
  final String posId;
  bool _isReady = false;

  InterstitialController(this.posId);

  /// 预加载广告
  Future<void> preload() async {
    try {
      final ok = await GromoreAds.loadInterstitialAd(
        posId,
        orientation: vertical, // 或 horizontal
        mutedIfCan: true,
      );
      _isReady = ok;
    } catch (e) {
      debugPrint('插屏广告加载失败: $e');
      _isReady = false;
    }
  }

  /// 展示广告(如未加载会先尝试加载)
  Future<bool> show() async {
    // 检查是否已加载
    if (!_isReady) {
      await preload();
    }

    // 加载失败,返回false
    if (!_isReady) {
      debugPrint('广告未就绪,无法展示');
      return false;
    }

    try {
      final ok = await GromoreAds.showInterstitialAd(posId);
      if (ok) {
        _isReady = false; // 展示后需重新加载
      }
      return ok;
    } catch (e) {
      debugPrint('插屏广告展示失败: $e');
      _isReady = false;
      return false;
    }
  }
}

🎯 要点

  • showInterstitialAd 仅在已经加载成功的情况下才会返回 true
  • 必须使用 try-catch 处理加载和展示过程中的异常
  • 展示成功后 _isReady 应重置为 false,避免重复展示

2. 参数配置详解

2.1 完整参数表

参数类型必需/可选默认值平台支持说明
posIdString必需-全平台广告位ID
orientationint?可选vertical(1)全平台方向(vertical=1, horizontal=2)
mutedIfCanbool?可选SDK默认全平台聚合SDK静音开关
volumedouble?可选1.0[Android]音量(0.0~1.0)
bidNotifybool?可选false全平台是否回传竞价结果
scenarioIdString?可选null全平台自定义场景ID
useSurfaceViewbool?可选false[Android]是否使用SurfaceView播放
showDirectionint?可选SDK默认[iOS]聚合额外方向配置
rewardNameString?可选null[iOS]奖励名称(GDT渠道专用)
rewardAmountint?可选null[iOS]奖励数量(GDT渠道专用)
customDataString?可选null全平台透传到原生的自定义数据(用于奖励校验)
extraDataMap?可选null全平台Android渠道扩展字段
extraParamsMap?可选null全平台iOS渠道扩展字段

2.2 参数使用原则

⚠️ 重要:仅传递需要自定义的可选参数,其余保持 null 即可让 SDK 使用默认行为。

参数传递策略

  • ✅ 只传递显式需要的参数
  • ✅ 未传递的参数会让SDK使用原生默认值
  • ❌ 不要为所有参数设置默认值(会破坏SDK的原生行为)

3. 平台差异说明

3.1 Android专属参数

以下参数仅在 Android 平台生效,iOS 平台会自动忽略:

参数类型说明使用场景
volumedouble?音量(0.0~1.0)需要精确控制音量时使用
useSurfaceViewbool?使用SurfaceView播放解决部分设备渲染问题

示例

// Android专属配置(iOS会忽略这些参数)
await GromoreAds.loadInterstitialAd(
  posId,
  volume: 0.5,  // @android 仅Android支持
  useSurfaceView: true,  // @android 仅Android支持
);

3.2 iOS专属参数

以下参数仅在 iOS 平台生效,Android 平台会自动忽略:

参数类型说明使用场景
showDirectionint?聚合额外方向配置需要特殊方向控制时使用
rewardNameString?奖励名称(GDT渠道)接入GDT渠道时使用
rewardAmountint?奖励数量(GDT渠道)接入GDT渠道时使用

示例

// iOS专属配置(Android会忽略这些参数)
await GromoreAds.loadInterstitialAd(
  posId,
  showDirection: 1,  // @ios 仅iOS支持
  rewardName: '金币',  // @ios GDT渠道专用
  rewardAmount: 100,  // @ios GDT渠道专用
);

3.3 跨平台开发建议

方式1:统一配置(推荐)

// 直接传递所有参数,平台会自动忽略不支持的参数
await GromoreAds.loadInterstitialAd(
  posId,
  orientation: vertical,
  mutedIfCan: true,
  volume: 0.5,  // Android使用,iOS忽略
  showDirection: 1,  // iOS使用,Android忽略
);

方式2:平台判断

import 'dart:io';

await GromoreAds.loadInterstitialAd(
  posId,
  orientation: vertical,
  mutedIfCan: true,
  volume: Platform.isAndroid ? 0.5 : null,
  showDirection: Platform.isIOS ? 1 : null,
);

💡 推荐做法:使用方式1(统一配置),代码更简洁,平台会自动处理参数差异。

4. 典型使用场景

  • 游戏关卡结束:关卡结束后调用 show(),并在事件监听里根据 interstitial_closed 继续游戏。
  • 功能解锁:用户完成某个步骤后展示一次,事件 interstitial_clicked 可用于统计转化。
  • 冷启动欢迎页:配合开屏广告预加载,减少等待时间。

5. 与事件结合

import 'package:gromore_ads/gromore_ads.dart';

class GameInterstitialListener extends OnAdEventListener {
  @override
  void onAdEvent(AdEvent event) {
    switch (event.action) {
      case 'interstitial_load_success':
        debugPrint('插屏广告加载成功');
        break;
      case 'interstitial_load_fail':
        debugPrint('插屏广告加载失败: ${event.extra}');
        break;
      case 'interstitial_show':
        debugPrint('插屏广告开始展示');
        break;
      case 'interstitial_click':
        debugPrint('插屏广告被点击');
        break;
      case 'interstitial_close':
        debugPrint('插屏广告关闭');
        _resumeGameplay();
        break;
    }
  }

  @override
  void onAdError(AdErrorEvent event) {
    debugPrint('插屏广告错误: ${event.message}');
  }

  void _resumeGameplay() {
    // 恢复游戏逻辑
  }
}

// 注册事件监听
AdEventSubscription? _subscription;

void initAds() {
  _subscription = GromoreAds.onInterstitialEvents(
    'your_interstitial_id',
    onLoaded: (event) => _controller.markReady(),
    onShowed: (event) => _controller.pauseGameplay(),
    onClosed: (event) => _controller.resumeGameplay(),
    onError: (event) => debugPrint('❌ 错误: ${event.message}'),
  );
}

将事件监听与控制器组合,即可实现完整的插屏广告生命周期管理。

6. 常见问题与故障排查

6.1 广告未就绪无法展示

问题:调用 showInterstitialAd 返回 false

原因

  • 广告未加载完成就尝试展示
  • 广告已展示过,需要重新加载
  • 加载失败但未检查状态

解决方案

class InterstitialController {
  bool _isReady = false;

  Future<bool> show() async {
    // ✅ 正确:先检查是否就绪
    if (!_isReady) {
      debugPrint('广告未就绪,先加载');
      await preload();
    }

    if (!_isReady) {
      debugPrint('加载失败,无法展示');
      return false;
    }

    final ok = await GromoreAds.showInterstitialAd(posId);
    if (ok) {
      _isReady = false;  // ✅ 展示后重置状态
    }
    return ok;
  }
}

6.2 广告加载失败

常见原因

  1. 广告位ID错误:检查posId是否正确
  2. SDK未初始化:确保在调用前已初始化SDK
  3. 网络问题:检查设备网络连接
  4. 频次限制:广告请求过于频繁被限制
  5. 无广告填充:当前时段无可用广告

调试步骤

// 1. 启用调试模式
await GromoreAds.initAd(
  appId,
  useMediation: true,
  debugMode: true,  // 开启调试
);

// 2. 监听加载事件
_subscription = GromoreAds.onInterstitialEvents(
  'your_interstitial_id',
  onLoaded: (event) {
    debugPrint('✅ 插屏广告加载成功');
  },
  onError: (event) {
    debugPrint('❌ 错误码: ${event.code}');
    debugPrint('错误信息: ${event.message}');
    debugPrint('广告位: ${event.posId}');
  },
);

6.3 展示时机控制

问题:如何在合适的时机展示广告?

建议

// ✅ 正确:预加载 + 延迟展示
class GameLevelController {
  final _interstitial = InterstitialController(posId);

  void onLevelStart() {
    // 关卡开始时预加载广告
    _interstitial.preload();
  }

  void onLevelComplete() {
    // 关卡结束后展示广告
    _interstitial.show();
  }
}

// ❌ 错误:临时加载,用户等待时间长
void onLevelComplete() {
  await GromoreAds.loadInterstitialAd(posId);  // 用户需要等待
  await GromoreAds.showInterstitialAd(posId);
}

6.4 如何避免重复展示

问题:同一个广告被展示多次

解决方案

class InterstitialController {
  bool _isShowing = false;

  Future<bool> show() async {
    // ✅ 防止重复展示
    if (_isShowing) {
      debugPrint('广告正在展示中');
      return false;
    }

    _isShowing = true;
    try {
      final ok = await GromoreAds.showInterstitialAd(posId);
      return ok;
    } finally {
      _isShowing = false;
    }
  }
}

6.5 调试建议

  1. 启用GroMore调试工具
await GromoreAds.launchTestTools();  // 启动官方调试工具
  1. 查看详细日志
await GromoreAds.initAd(
  appId,
  useMediation: true,
  debugMode: true,  // 输出详细日志
);
  1. 使用单元测试页面
    • 验证参数配置是否正确
    • 测试平台差异处理
    • 检查事件回调是否完整

💡 提示:遇到问题时,优先检查事件回调日志,大多数问题都能从事件中找到原因。

需要进一步协助?

与 LightCore 技术顾问沟通,获取商业化策略与集成支持。