---
metadata:
  - name: generator
    content: Diplodoc Platform v5.52.0
alternate:
  - https://ads.yandex.com/helpcenter/en/dev/flutter/app-open-ad.md
  - https://ads.yandex.com/helpcenter/ru/dev/flutter/app-open-ad.md
  - https://ads.yandex.com/helpcenter/zh/dev/flutter/app-open-ad.md
  - href: zh/dev/flutter/app-open-ad.md
    type: text/markdown
    title: Markdown version
  - href: llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://ads.yandex.com/helpcenter/zh/llms.txt

# 开屏广告

<!-- source: zh/dev/_includes/app-open-ad.md -->
应用开屏广告是一种用于通过应用加载界面实现变现的特殊广告格式。此类广告可随时关闭，并设计用于在以下场景中展示：
* 应用启动时。
* 应用被调至前台时。
* 从后台返回应用时。
<!-- endsource: zh/dev/_includes/app-open-ad.md -->

本指南将展示如何将开屏广告集成到 Flutter 应用中。除了代码示例和说明之外，它还包含特定格式的建议和其他资源的链接。

<!-- source: zh/dev/_includes/app-open-ad.md -->
{% note alert %}

应用开屏广告仅支持纵向布局的应用。对于横向布局的应用，此类广告将不会展示。

{% endnote %}
<!-- endsource: zh/dev/_includes/app-open-ad.md -->

# 布局

开屏广告包含 **登录应用程序** 按钮，以便用户知道他们正在使用您的应用并可以关闭广告。以下是广告的示例：

<iframe width="200" height="405.5" allow="autoplay" src="https://runtime.strm.yandex.ru/player/video/vplvlddx5n2gyycnvb6g?autoplay=1&mute=0&loop=1" frameborder="0" allowfullscreen></iframe>

## 前提条件 {#pre}

<!-- source: zh/dev/_includes/pre-flutter.md -->
1. 按照 [快速入门](https://ads.yandex.com/helpcenter/zh/dev/flutter/quick-start.md) 中的流程集成 Yandex Mobile Ads Flutter 插件。
2. 确保您运行的是最新的 [Yandex Mobile Ads Flutter 插件](https://ads.yandex.com/helpcenter/zh/dev/platforms.md) 版本。如果您使用聚合，请确保您运行的是最新版本的 [统一构建](https://ads.yandex.com/helpcenter/zh/dev/platforms.md)。
<!-- endsource: zh/dev/_includes/pre-flutter.md -->

### 术语和定义

* **冷启动** 是指启动一个不在 RAM 中的应用，创建一个新的应用会话。
* **热启动** 是指当应用在 RAM 中暂停时，将应用从后台模式切换到前台模式。

## 实施 {#implement}

1. 创建 `AppOpenAdLoader` 广告加载器并安装广告加载事件的回调函数。
2. 在 `AdRequestConfiguration` 中设置广告加载参数。
3. 使用 `AppOpenAdLoader.LoadAd(AdRequestConfiguration)` 方法加载广告。
4. 使用 `WidgetsBindingObserver` 接口中的 `didChangeAppLifecycleState` 方法来处理应用状态变化并显示开屏广告。
5. 为用户与您的广告互动的事件安装回调函数。
6. 通过调用 `AppOpenAd.Show()` 方法展示广告。
7. 释放资源。

### 主要步骤 

1. 创建 `AppOpenAdLoader` 广告加载器并注册广告加载事件的监听器。

   ```dart
   @override
   void initState() {
       super.initState();
       YandexAds.initialize();
       _appOpenAdLoader = _createAppOpenAdLoader();
   }
   
   late final Future<AppOpenAdLoader> _appOpenAdLoader;
   AppOpenAd? _appOpenAd;
   
   Future<AppOpenAdLoader> _createAppOpenAdLoader() {
       return AppOpenAdLoader.create(
           onAdLoaded: (AppOpenAd appOpenAd) {
               // 广告加载成功。现在您可以处理它了。
               _appOpenAd = appOpenAd;
           },
           onAdFailedToLoad: (error) {
               // 广告加载失败并出现错误
               // 强烈建议不要尝试从 OnAdFailedToLoad 事件加载新广告。
           },
       );
   }

2. 在 `AdRequestConfiguration` 中设置广告加载参数。

   ```dart
   final _adUnitId = 'demo-appopenad-yandex'; // 替换为 "R-M-XXXXXX-Y"
   late var _adRequestConfiguration = AdRequestConfiguration(adUnitId: _adUnitId);
   ```

   `AdUnitId`：在 Yandex Advertising Network 界面中发布的唯一标识符，如下所示：R-M-XXXXXX-Y。

   {% note tip %}

   出于测试目的，您可以使用演示广告单元 ID："demo-appopenad-yandex"。在发布广告之前，请确保将演示单元 ID 替换为真实的广告单元 ID。

   您可以使用 `AdRequestConfiguration` 扩展广告请求参数，将用户兴趣、上下文页面数据、位置详细信息或其他数据作为附加参数传递。在请求中提供额外的上下文数据可以显著提高您的广告质量。请参阅[广告定位](https://ads.yandex.com/helpcenter/zh/dev/flutter/target.md)版块了解更多信息。

   {% endnote %}

3. 使用 `LoadAd` 方法加载广告，并将 `AdRequestConfiguration` 作为参数传递。

   ```dart
   Future<void> _loadAppOpenAd() async {
       final adLoader = await _appOpenAdLoader;
       await adLoader.loadAd(adRequestConfiguration: _adRequestConfiguration);
   }

4. 使用 `WidgetsBindingObserver` 接口中的 `didChangeAppLifecycleState` 方法来处理应用状态变化并显示开屏广告。

   ```dart
   @override
   void initState() {
       super.initState();
       // ...
       WidgetsBinding.instance.addObserver(this);
   }

   @override
   void didChangeAppLifecycleState(AppLifecycleState state) {
       if (state == AppLifecycleState.resumed) {
           _showAdIfAvailable();
       }
   }
   ```

5. 注册用户与您的广告互动的事件的监听器。

   ```dart
   static var isAdShowing = false;
   
   void _setAdEventListener({required AppOpenAd appOpenAd }) {
       appOpenAd.setAdEventListener(
           eventListener: AppOpenAdEventListener(
               onAdShown: () {
                   // 广告展示时调用。
                   isAdShowing = true;
               },
               onAdFailedToShow: (error) {
                   // 广告展示失败时调用。
                   isAdShowing = false;
   
                   // 广告关闭后清除资源。
                   _clearAppOpenAd();
                   // 现在您可以预加载下一个广告。
                   _loadAppOpenAd();
               },
               onAdDismissed: () {
                   // 广告关闭时调用。
                   isAdShowing = false;
   
                   // 清除资源。
                   _clearAppOpenAd();
                   // 现在您可以预加载下一个广告。
                   _loadAppOpenAd();
               },
               onAdClicked: () {
                   // 记录广告点击时调用。
               },
               onAdImpression: (data) {
                   // 记录广告展示次数时调用。
               }
           )
       );
   }

6. 通过调用 `AppOpenAd.Show()` 方法展示广告。

   ```dart
   Future<void> _showAdIfAvailable() async {
       var appOpenAd = _appOpenAd;
       if (appOpenAd != null && !isAdShowing) {
           _setAdEventListener(appOpenAd: appOpenAd);
           await appOpenAd.show();
           await appOpenAd.waitForDismiss();
       } else {
           _loadAppOpenAd();
       }
   }

7. 如果您不再使用所显示广告的链接，请清除它们。这可以释放资源并防止内存泄漏。

   ```dart
   void _clearAppOpenAd() {
       _appOpenAd?.destroy();
       _appOpenAd = null;
   }

### 完整代码示例

```dart
class _AppOpenAdPageState extends State<AppOpenAdPage> with WidgetsBindingObserver {
    final _adUnitId = 'demo-appopenad-yandex';
    late var _adRequestConfiguration = AdRequestConfiguration(adUnitId: _adUnitId);
    AppOpenAd? _appOpenAd;
    late final Future<AppOpenAdLoader> _appOpenAdLoader = _createAppOpenAdLoader();

    static var isAdShowing = false;
    static var isColdStartAdShown = false;

    Future<AppOpenAdLoader> _createAppOpenAdLoader() {
        return AppOpenAdLoader.create(
            onAdLoaded: (AppOpenAd appOpenAd) {
                // 广告加载成功。现在您可以处理它了。
                _appOpenAd = appOpenAd;

                if (!isColdStartAdShown) {
                    _showAdIfAvailable();
                    isColdStartAdShown = true;
                }
            },
            onAdFailedToLoad: (error) {
                // 广告加载失败
                // 强烈建议不要尝试从 OnAdFailedToLoad 事件加载新广告。
            },
        );
    }

    @override
    void initState() {
        super.initState();
        YandexAds.initialize();
        _appOpenAdLoader = _createAppOpenAdLoader();
        _loadAppOpenAd();
        WidgetsBinding.instance.addObserver(this);
    }

    Future<void> _loadAppOpenAd() async {
        final adLoader = await _appOpenAdLoader;
        await adLoader.loadAd(adRequestConfiguration: _adRequestConfiguration);
    }

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
        if (state == AppLifecycleState.resumed) {
            _showAdIfAvailable();
        }
    }

    void _setAdEventListener({required AppOpenAd appOpenAd }) {
        appOpenAd.setAdEventListener(
            eventListener: AppOpenAdEventListener(
                onAdShown: () {
                    // 广告展示时调用。
                    isAdShowing = true;
                },
                onAdFailedToShow: (error) {
                    // 广告展示失败时调用。

                    // 广告关闭后清除资源。
                    _clearAppOpenAd();
                    // 现在您可以预加载下一个广告。
                    _loadAppOpenAd();
                },
                onAdDismissed: () {
                    // 广告关闭时调用。
                    isAdShowing = false;

                    // 清除资源。
                    _clearAppOpenAd();
                    // 现在您可以预加载下一个广告。
                    _loadAppOpenAd();
                },
                onAdClicked: () {
                    // 记录广告点击时调用。
                },
                onAdImpression: (data) {
                    // 记录广告展示次数时调用。
                }
            )
        );
    }

    Future<void> _showAdIfAvailable() async {
        var appOpenAd = _appOpenAd;
        if (appOpenAd != null && !isAdShowing) {
            _setAdEventListener(appOpenAd: appOpenAd);
            await appOpenAd.show();
            await appOpenAd.waitForDismiss();
        } else {
            loadAppOpenAd();
        }
    }

    void _clearAppOpenAd() {
        _appOpenAd?.destroy();
        _appOpenAd = null;
    }
}
```

## 开屏广告集成的特点 {#features}

1. 加载可能需要一段时间，因此如果广告尚未加载，请勿增加冷启动时间。
2. 预加载广告以便后续在热启动期间显示。
3. 我们不建议您在应用启动期间同时加载开屏广告和其他广告格式，因为此时应用可能正在下载运营数据。这可能会使设备和互联网连接超载，从而导致广告加载时间变长。
4. 如果您在 `onAdFailedToLoad` 事件中收到错误，请不要尝试再次加载新广告。如果必须这样做，请限制广告重新加载尝试的次数。这将有助于避免出现限制时持续出现不成功的请求和连接问题。

## 在发布时测试广告集成 {#test}

{% list tabs %}

- Android

   <!-- source: zh/dev/_includes/test-android-app-open-ad.md -->
   ### 使用演示广告单元进行广告测试 {#demo-blocks}

   使用测试广告来检查您的广告集成和应用本身。为了确保每次广告请求都能返回测试广告，您可以使用一个特殊的演示广告版位 ID。

   演示广告单元 ID：`demo-appopenad-yandex`。

   {% note warning %}

   在应用商店发布应用前，请务必将演示广告版位 ID 替换为您在 Yandex Advertising Network 接口中获取的真实 ID。

   {% endnote %}

   有关所有可用演示广告版位 ID 的列表，请参阅[用于测试的演示广告单元](https://ads.yandex.com/helpcenter/zh/dev/android/demo-blocks.md)。

   ### 测试广告集成 {#test-int}

   您可以使用 SDK 的内置分析工具检查应用的开屏广告是否已正确集成。日志中将显示包含测试结果的详细报告。

   要查看报告，请在 Android 应用调试工具 [Logcat](https://developer.android.com/studio/command-line/logcat) 中搜索关键词“YandexAds”。
   ```bash
   adb logcat -v brief '*:S YandexAds'
   ```

   如果集成成功，将返回以下消息：
   ```bash
   adb logcat -v brief '*:S YandexAds'
   mobileads$ adb logcat -v brief '*:S YandexAds'
   I/YandexAds(13719): [Integration] Ad type App Open Ad was integrated successfully
   ```

   如果存在任何广告集成问题，您将收到详细的问题报告和故障排除建议。
   <!-- endsource: zh/dev/_includes/test-android-app-open-ad.md -->

- iOS

   <!-- source: zh/dev/_includes/test-ios-app-open-ad.md -->
   ### 使用演示广告单元进行广告测试 {#demo-blocks}

   我们建议使用测试广告来测试开屏广告集成和应用本身。

   为了保证为每个广告请求返回测试广告，我们创建了一个特殊的演示广告版位 ID。用它来检查您的广告集成。

   演示广告单元 ID：`demo-appopenad-yandex`。

   {% note warning %}

   在商店中发布您的应用程序之前，确保将演示版位 ID 替换为您在 Yandex Advertising Network 界面中获得的真实 ID。

   {% endnote %}

   您可以在 [用于测试的演示广告单元](https://ads.yandex.com/helpcenter/zh/dev/ios/demo-blocks.md) 版块找到可用的演示广告版位 ID 列表。
   <!-- endsource: zh/dev/_includes/test-ios-app-open-ad.md -->

   ### 测试广告集成

   <!-- source: zh/dev/_includes/test-integration-ios.md -->
   您可以使用本机控制台工具测试广告集成。

   要查看详细日志，请调用 `YMAMobileAds` 类的 `enableLogging` 方法。

   ```swift
   YMAMobileAds.enableLogging()
   ```

   要查看 SDK 日志，请前往控制台工具并设置 `Subsystem = com.mobile.ads.ads.sdk`。您还可以按类别和错误级别过滤日志。

   如果您在集成广告时遇到问题，您将获得有关问题的详细报告以及如何解决这些问题的建议。

   <img src= "https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/common/integration-ios-2.png">
   <!-- endsource: zh/dev/_includes/test-integration-ios.md -->

{% endlist %}

## 建议

1. 不要在启动屏幕之前呈现开屏广告。

   通过显示启动屏幕，您可以增强用户的应用体验，使其更加流畅，令用户愉悦。这将避免用户感到惊讶或困惑，并确保他们打开了正确的应用。在同一屏幕上，您可以提醒用户即将展示的广告。使用加载指示器或简单的文本信息告知用户他们将在广告结束后继续查看应用内容。

2. 如果请求和呈现广告之间存在延迟，用户可能会短暂打开您的应用，然后意外地看到与内容无关的广告。这会对用户体验产生负面影响，因此需要避免。一种解决方案是在显示主应用内容之前使用启动屏幕，并从该屏幕开始广告呈现。如果应用在启动屏幕后打开一些内容，则最好不要呈现广告。

3. 等到新用户打开应用并使用几次后，再呈现开屏广告。仅向应用中满足特定条件的用户呈现广告（例如，通过了特定级别、打开了特定次数的应用或未参与奖励优惠）。不要在用户安装应用后立即呈现广告。

4. 根据应用用户行为调节广告呈现频率。不要在每次冷/热应用启动时呈现广告。

5. 仅当应用在后台运行一段时间（例如 30 秒、2 分钟、15 分钟）时才呈现广告。

6. 确保运行了彻底的测试，因为每款应用都是独特的，并且需要特殊的方法来最大限度地提高收入，而不降低用户留存率或减少花费在应用上的时间。用户行为和参与度可能会随着时间的推移而发生变化，因此我们建议定期测试您用于开屏广告的策略。

## 其他资源 {#resources}

您可以在此处查找完整的集成示例：

* <!-- source: zh/dev/_includes/github-pubdev-links.md -->
  [Pub.dev](https://pub.dev/packages/yandex_mobileads/example) 链接。
  <!-- endsource: zh/dev/_includes/github-pubdev-links.md -->
* <!-- source: zh/dev/_includes/github-pubdev-links.md -->
  [GitHub](https://github.com/yandexmobile/yandex-ads-flutter-plugin) 链接。
  <!-- endsource: zh/dev/_includes/github-pubdev-links.md -->

