---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ads.yandex.com/helpcenter/en/dev/android/release/8-0-0-migration.md
  - https://ads.yandex.com/helpcenter/ru/dev/android/release/8-0-0-migration.md
  - https://ads.yandex.com/helpcenter/zh/dev/android/release/8-0-0-migration.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ads.yandex.com/helpcenter/zh/llms.txt

# 迁移至版本 8 的指南

Yandex Mobile Ads SDK 版本 8 引入了多项 API 变更，旨在提升开发者体验。

{% note tip "使用 AI 工具迁移" %}

为加快从 SDK 7.x 到 8.x 的迁移，可使用内置迁移技能的 AI 助手，详情参见[使用 AI 工具迁移](#ai)章节。

{% endnote %}

## 主要变更

### 1. AdRequest 变更

已移除 `AdRequestConfiguration` 和 `NativeAdRequestConfiguration` 类。 对所有广告格式使用 `AdRequest`。

#|
|| **类** | **状态** ||
|| `AdRequestConfiguration` | 已移除。 使用 `AdRequest` ||
|| `NativeAdRequestConfiguration` | 已移除。 使用 `AdRequest` 和 `NativeAdOptions` ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   // 全屏广告和原生广告，例如 InterstitialAdLoader
   val loader = InterstitialAdLoader(this)
   val config = AdRequestConfiguration.Builder("R-M-XXXXX-YY").build()
   loader.loadAd(config)

   // 横幅广告
   val bannerView = findViewById<R.id.view_banner>(BannerAdView)
   bannerView.setAdUnitId("R-M-XXXXX-YY")
   val request = AdRequest.Builder().build()
   bannerView.loadAd(request)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   // 全屏广告和原生广告，例如 InterstitialAdLoader
   val loader = InterstitialAdLoader(this)
   val request = AdRequest.Builder("R-M-XXXXX-YY").build()
   loader.loadAd(adRequest, listener)

   // 横幅广告
   val bannerView = findViewById<R.id.view_banner>(BannerAdView)
   val request = AdRequest.Builder("R-M-XXXXX-YY").build()
   bannerView.loadAd(request)
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAd() {
       // 全屏广告和原生广告，例如 InterstitialAdLoader
       InterstitialAdLoader loader = new InterstitialAdLoader(this);
       AdRequestConfiguration config = new AdRequestConfiguration.Builder("R-M-XXXXX-YY")
               .build();
       loader.loadAd(config);

       // 横幅广告
       BannerAdView bannerView = findViewById(R.id.view_banner);
       bannerView.setAdUnitId("R-M-XXXXX-YY");
       AdRequest request = AdRequest.Builder().build();
       bannerView.loadAd(request);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAd() {
       // 全屏广告与原生广告，例如 InterstitialAdLoader
       InterstitialAdLoader loader = new InterstitialAdLoader(this);
       AdRequest request = new AdRequest.Builder("R-M-XXXXX-YY")
               .build();
       loader.loadAd(request, listener);

       // 横幅广告
       BannerAdView bannerView = findViewById(R.id.view_banner);
       AdRequest request = new AdRequest.Builder("R-M-XXXXX-YY").build();
       bannerView.loadAd(request);
   }
   ```
   ||
   |#

{% endlist %}

### 2. 定位 API 变更

- 字段 `age`、`gender`、`location`、`contextQuery` 和 `contextTags` 已从 `AdRequest.Builder` 中移除。
- 要管理定位参数，请使用新的 `AdTargeting` 类。

#|
|| **类** | **状态** ||
|| `AdTargeting` | 已添加 ||
|| `AdTargeting.Builder` | 已添加 ||
|#

#|
|| **类** | **方法** | **状态** ||
|| `AdRequest.Builder` | `setAge(String)` | 已移除。 使用 `AdTargeting.Builder.setAge(String)` 和 `AdRequest.Builder.setTargeting(AdTargeting)` ||
|| ^ | `setGender(String)` | 已移除。 使用 `AdTargeting.Builder.setGender(String)` 和 `AdRequest.Builder.setTargeting(AdTargeting)` ||
|| ^ | `setLocation(Location)` | 已移除。 使用 `AdTargeting.Builder.setLocation(Location)` 和 `AdRequest.Builder.setTargeting(AdTargeting)` ||
|| ^ | `setContextQuery(String)` | 已移除。 使用 `AdTargeting.Builder.setContextQuery(String)` 和 `AdRequest.Builder.setTargeting(AdTargeting)` ||
|| ^ | `setContextTags(List<String>)` | 已移除。 使用 `AdTargeting.Builder.setContextTags(List<String>)` 和 `AdRequest.Builder.setTargeting(AdTargeting)` ||
|| ^ | `setTargeting(AdTargeting)` | 已添加 ||
|| `AdTargeting.Builder` | `setAge(String)` | 已添加 ||
|| ^ | `setGender(String)` | 已添加 ||
|| ^ | `setLocation(Location)` | 已添加 ||
|| ^ | `setContextQuery(String)` | 已添加 ||
|| ^ | `setContextTags(List<String>)` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   val adRequest = AdRequest.Builder()
       .setAge("25")
       .setGender(Gender.MALE)
       .setContextTags(listOf("news"))
       .build()
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   val targeting = AdTargeting.Builder()
       .setAge("25")
       .setGender(Gender.MALE)
       .setContextTags(listOf("news"))
       .build()

   val adRequest = AdRequest.Builder(adUnitId)
       .setTargeting(targeting)
       .build()
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAd() {
       AdRequest adRequest = AdRequest.Builder()
               .setAge("25")
               .setGender(Gender.MALE)
               .setContextTags(listOf("news"))
               .build();
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAd() {
       AdTargeting targeting = new AdTargeting.Builder()
               .setAge("25")
               .setGender(Gender.MALE)
               .setContextTags(listOf("news"))
               .build();

       AdRequest adRequest = new AdRequest.Builder(adUnitId)
               .setTargeting(targeting)
               .build();
   }
   ```
   ||
   |#

{% endlist %}

### 3. 广告加载 API 变更

注册回调方法和广告加载监听器已更新。

#|
|| **类** | **方法** | **状态** ||
|| InterstitialAdLoader | `setAdLoadListener(InterstitialAdLoadListener)` | 已移除。 将 `InterstitialAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAd(AdRequestConfiguration)` | 已移除。 使用 `loadAd(AdRequest, InterstitialAdLoadListener)`。 ||
|| ^ | `loadAd(AdRequest, InterstitialAdLoadListener)` | 已添加 ||
|| RewardedAdLoader | `setAdLoadListener(RewardedAdLoadListener)` | 已移除。 将 `RewardedAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAd(AdRequestConfiguration)` | 已移除。 使用 `loadAd(AdRequest, RewardedAdLoadListener)`。 ||
|| ^ | `loadAd(AdRequest, RewardedAdLoadListener)` | 已添加 ||
|| AppOpenAdLoader | `setAdLoadListener(AppOpenAdLoadListener)` | 已移除。 将 `AppOpenAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAd(AdRequestConfiguration)` | 已移除。 使用 `loadAd(AdRequest, AppOpenAdLoadListener)`。 ||
|| ^ | `loadAd(AdRequest, AppOpenAdLoadListener)` | 已添加 ||
|| NativeAdLoader | `setNativeAdLoadListener(NativeAdLoadListener)` | 已移除。 将 `NativeAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAd(NativeAdRequestConfiguration)` | 已移除。 使用 `loadAd(AdRequest, NativeAdLoadListener)`。 ||
|| ^ | `loadAd(AdRequest, NativeAdOptions, NativeAdLoadListener)` | 已添加 ||
|| ^ | `loadAd(AdRequest, NativeAdLoadListener)` | 已添加 ||
|| SliderAdLoader | `setSliderAdLoadListener(SliderAdLoadListener)` | 已移除。 将 `SliderAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadSlider(NativeAdRequestConfiguration)` | 已移除。 使用 `loadAd(AdRequest, SliderAdLoadListener)`。 ||
|| ^ | `loadSlider(AdRequest, NativeAdOptions, SliderAdLoadListener)` | 已添加 ||
|| ^ | `loadAd(AdRequest, NativeAdLoadListener)` | 已添加 ||
|| NativeBulkAdLoader | `setNativeBulkAdLoadListener(NativeBulkAdLoadListener)` | 已移除。 将 `NativeBulkAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAds(NativeAdRequestConfiguration, Int)` | 已移除。 使用 `loadAd(AdRequest, NativeAdLoadListener)`。 ||
|| ^ | `loadAds(AdRequest, NativeAdOptions, NativeBulkAdLoadListener)` | 已添加 ||
|| ^ | `loadAds(AdRequest, NativeBulkAdLoadListener)` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   // 插屏广告
   val interstitialAdLoader = InterstitialAdLoader(this)
   interstitialAdLoader.setAdLoadListener(object : InterstitialAdLoadListener { /* ... */ })
   interstitialAdLoader.loadAd(AdRequestConfiguration.Builder("R-M-XXXXX-YY").build())

   // 激励广告
   val rewardedAdLoader = RewardedAdLoader(this)
   rewardedAdLoader.setAdLoadListener(object : RewardedAdLoadListener { /* ... */ })
   rewardedAdLoader.loadAd(AdRequestConfiguration.Builder("R-M-XXXXX-YY").build())

   // 开屏广告
   val appOpenAdLoader = AppOpenAdLoader(this)
   appOpenAdLoader.setAdLoadListener(object : AppOpenAdLoadListener { /* ... */ })
   appOpenAdLoader.loadAd(AdRequestConfiguration.Builder("R-M-XXXXX-YY").build())

   // 原生广告
   val nativeAdLoader = NativeAdLoader(this)
   nativeAdLoader.setNativeAdLoadListener(object : NativeAdLoadListener { /* ... */ })
   nativeAdLoader.loadAd(NativeAdRequestConfiguration.Builder("R-M-XXXXX-YY").build())

   // 滑动广告
   val sliderAdLoader = SliderAdLoader(this)
   sliderAdLoader.setSliderAdLoadListener(object : SliderAdLoadListener { /* ... */ })
   sliderAdLoader.loadSlider(NativeAdRequestConfiguration.Builder("R-M-XXXXX-YY").build())

   // 原生批量广告
   val nativeBulkAdLoader = NativeBulkAdLoader(this)
   nativeBulkAdLoader.setNativeBulkAdLoadListener(object : NativeBulkAdLoadListener { /* ... */ })
   nativeBulkAdLoader.loadAds(NativeAdRequestConfiguration.Builder("R-M-XXXXX-YY").build(), 1)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   // 插屏广告
   val interstitialAdLoader = InterstitialAdLoader(this)
   interstitialAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build(), object : InterstitialAdLoadListener { /* ... */ })

   // 激励广告
   val rewardedAdLoader = RewardedAdLoader(this)
   rewardedAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build(), object : RewardedAdLoadListener { /* ... */ })

   // 开屏广告
   val appOpenAdLoader = AppOpenAdLoader(this)
   appOpenAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build(), object : AppOpenAdLoadListener { /* ... */ })

   // 原生广告
   val nativeAdLoader = NativeAdLoader(this)
   nativeAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build(), object : NativeAdLoadListener { /* ... */ })
   // Or with NativeAdOptions
   nativeAdLoader.loadAd(
       AdRequest.Builder("R-M-XXXXX-YY").build(),
       NativeAdOptions.Builder().build(),
       object : NativeAdLoadListener { /* ... */ })

   // 滑动广告
   val sliderAdLoader = SliderAdLoader(this)
   sliderAdLoader.loadSlider(AdRequest.Builder("R-M-XXXXX-YY").build(), object : SliderAdLoadListener { /* ... */ })
   // Or with NativeAdOptions
   sliderAdLoader.loadSlider(
       AdRequest.Builder("R-M-XXXXX-YY").build(),
       NativeAdOptions.Builder().build(),
       object : SliderAdLoadListener { /* ... */ })

   // 原生批量广告
   val nativeBulkAdLoader = NativeBulkAdLoader(this)
   nativeBulkAdLoader.loadAds(
       AdRequest.Builder("R-M-XXXXX-YY").build(),
       1,
       object : NativeBulkAdLoadListener { /* ... */ }
   )
   // Or with NativeAdOptions
   nativeBulkAdLoader.loadAds(
       AdRequest.Builder("R-M-XXXXX-YY").build(),
       1,
       NativeAdOptions.Builder().build(),
       object : NativeBulkAdLoadListener { /* ... */ }
   )
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAd() {
       // 插屏广告
       InterstitialAdLoader interstitialAdLoader = new InterstitialAdLoader(this);
       interstitialAdLoader.setAdLoadListener(new InterstitialAdLoadListener() { /* ... */ });
       interstitialAdLoader.loadAd(new AdRequestConfiguration.Builder("R-M-XXXXX-YY").build());

       // 激励广告
       RewardedAdLoader rewardedAdLoader = new RewardedAdLoader(this);
       rewardedAdLoader.setAdLoadListener(new RewardedAdLoadListener() { /* ... */ });
       rewardedAdLoader.loadAd(new AdRequestConfiguration.Builder("R-M-XXXXX-YY").build());

       // 开屏广告
       AppOpenAdLoader appOpenAdLoader = new AppOpenAdLoader(this);
       appOpenAdLoader.setAdLoadListener(new AppOpenAdLoadListener() { /* ... */ });
       appOpenAdLoader.loadAd(new AdRequestConfiguration.Builder("R-M-XXXXX-YY").build());

       // 原生广告
       NativeAdLoader nativeAdLoader = new NativeAdLoader(this);
       nativeAdLoader.setNativeAdLoadListener(new NativeAdLoadListener() { /* ... */ });
       nativeAdLoader.loadAd(new NativeAdRequestConfiguration.Builder("R-M-XXXXX-YY").build());

       // 滑动广告
       SliderAdLoader sliderAdLoader = new SliderAdLoader(this);
       sliderAdLoader.setSliderAdLoadListener(new SliderAdLoadListener() { /* ... */ });
       sliderAdLoader.loadSlider(new NativeAdRequestConfiguration.Builder("R-M-XXXXX-YY").build());

       // 原生批量广告
       NativeBulkAdLoader nativeBulkAdLoader = new NativeBulkAdLoader(this);
       nativeBulkAdLoader.setNativeBulkAdLoadListener(new NativeBulkAdLoadListener() { /* ... */ });
       nativeBulkAdLoader.loadAds(new NativeAdRequestConfiguration.Builder("R-M-XXXXX-YY").build(), 1);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAd() {
       // 插屏广告
       InterstitialAdLoader interstitialAdLoader = new InterstitialAdLoader(this);
       interstitialAdLoader.loadAd(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new InterstitialAdLoadListener() { /* ... */ }
       );

       // 激励广告
       RewardedAdLoader rewardedAdLoader = new RewardedAdLoader(this);
       rewardedAdLoader.loadAd(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new RewardedAdLoadListener() { /* ... */ }
       );

       // 开屏广告
       AppOpenAdLoader appOpenAdLoader = new AppOpenAdLoader(this);
       appOpenAdLoader.loadAd(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new AppOpenAdLoadListener() { /* ... */ }
       );

       // 原生广告
       NativeAdLoader nativeAdLoader = new NativeAdLoader(this);
       nativeAdLoader.loadAd(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new NativeAdLoadListener() { /* ... */ }
       );
       // Or with NativeAdOptions
       nativeAdLoader.loadAd(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new NativeAdOptions.Builder().build(),
               new NativeAdLoadListener() { /* ... */ }
       );

       // 滑动广告
       SliderAdLoader sliderAdLoader = new SliderAdLoader(this);
       sliderAdLoader.loadSlider(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new SliderAdLoadListener() { /* ... */ }
       );
       // Or with NativeAdOptions
       sliderAdLoader.loadSlider(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               new NativeAdOptions.Builder().build(),
               new SliderAdLoadListener() { /* ... */ }
       );

       // 原生批量广告
       NativeBulkAdLoader nativeBulkAdLoader = new NativeBulkAdLoader(this);
       nativeBulkAdLoader.loadAds(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               1,
               new NativeBulkAdLoadListener() { /* ... */ }
       );
       // Or with NativeAdOptions
       nativeBulkAdLoader.loadAds(new AdRequest.Builder("R-M-XXXXX-YY").build(),
               1,
               new NativeAdOptions.Builder().build(),
               new NativeBulkAdLoadListener() { /* ... */ }
       );
   }
   ```
   ||
   |#

{% endlist %}

### 3.1 Kotlin 协程支持

API 现提供广告加载方法的 `suspend` 重载：

#|
|| **类** | **方法** | **状态** ||
|| InterstitialAdLoader | `suspend fun loadAd(AdRequest): InterstitialAdLoadResult` | 已添加 ||
|| RewardedAdLoader | `suspend fun loadAd(AdRequest): RewardedAdLoadResult` | 已添加 ||
|| AppOpenAdLoader | `suspend fun loadAd(AdRequest): AppOpenAdLoadResult` | 已添加 ||
|| NativeAdLoader | `suspend fun loadAd(AdRequest, NativeAdOptions): NativeAdLoadResult` | 已添加 ||
|| ^ | `suspend fun loadAd(AdRequest): NativeAdLoadResult` | 已添加 ||
|| SliderAdLoader | `suspend fun loadAd(AdRequest): SliderAdLoadResult` | 已添加 ||
|| ^ | `suspend fun loadAd(AdRequest, NativeAdOptions): SliderAdLoadResult` | 已添加 ||
|| NativeBulkAdLoader | `suspend fun loadAds(AdRequest, Int): NativeBulkAdLoadResult` | 已添加 ||
|| ^ | `suspend fun loadAds(AdRequest, Int, NativeAdOptions): NativeBulkAdLoadResult` | 已添加 ||
|#

#### 示例

```kotlin
lifecycleScope.launch {
    // 插屏广告
    val interstitialAdLoader = InterstitialAdLoader(applicationContext)
    when(val result = interstitialAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build())) {
        is InterstitialAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is InterstitialAdLoadResult.Success -> TODO("Show interstitial ad: ${result.ad}")
    }

    // 激励广告
    val rewardedAdLoader = RewardedAdLoader(applicationContext)
    when(val result = rewardedAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build())) {
        is RewardedAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is RewardedAdLoadResult.Success -> TODO("Show rewarded ad: ${result.ad}")
    }

    // 开屏广告
    val appOpenAdLoader = AppOpenAdLoader(applicationContext)
    when(val result = appOpenAdLoader.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build())) {
        is AppOpenAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is AppOpenAdLoadResult.Success -> TODO("Show appOpen ad: ${result.ad}")
    }

    // 原生广告
    val nativeAdLoader = NativeAdLoader(applicationContext)
    val nativeAdRequest = AdRequest.Builder("R-M-XXXXX-YY").build()
    when(val result = nativeAdLoader.loadAd(nativeAdRequest)) {
        is NativeAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is NativeAdLoadResult.Success -> TODO("Show native ad: ${result.ad}")
    }

    // Or with NativeAdOptions
    when(val result = nativeAdLoader.loadAd(nativeAdRequest, NativeAdOptions.Builder().build())) {
        is NativeAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is NativeAdLoadResult.Success -> TODO("Show native ad: ${result.ad}")
    }

    // 滑动广告
    val sliderAdLoader = SliderAdLoader(applicationContext)
    val sliderAdRequest = AdRequest.Builder("R-M-XXXXX-YY").build()
    when(val result = sliderAdLoader.loadAd(sliderAdRequest)) {
        is SliderAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is SliderAdLoadResult.Success -> TODO("Show slider ad: ${result.ad}")
    }

    // Or with NativeAdOptions
    when(val result = sliderAdLoader.loadAd(sliderAdRequest, NativeAdOptions.Builder().build())) {
        is SliderAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is SliderAdLoadResult.Success -> TODO("Show slider ad: ${result.ad}")
    }

    // 原生批量广告
    val nativeBulkAdLoader = NativeBulkAdLoader(applicationContext)
    val builkAdRequest = AdRequest.Builder("R-M-XXXXX-YY").build()
    when(val result = nativeBulkAdLoader.loadAds(builkAdRequest, 1)) {
        is NativeBulkAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is NativeBulkAdLoadResult.Success -> TODO("Show bulk ad: ${result.ads}")
    }

    // Or with NativeAdOptions
    when(val result = nativeBulkAdLoader.loadAds(builkAdRequest, 1, NativeAdOptions.Builder().build())) {
        is NativeBulkAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is NativeBulkAdLoadResult.Success -> TODO("Show bulk ad: ${result.ads}")
    }
}
```

### 4. 横幅 API 变更

`setAdUnitId` 方法已从 `BannerAdView` 中移除。 现在，为每个广告加载设置了 `adUnitId`。
用于创建 `BannerAdSize` 的工厂方法已重命名。

#|
|| **类** | **方法** | **状态** ||
|| `BannerAdView` | `setAdUnitId(String)` | 已移除。 在加载广告之前，请将 `adUnitId` 属性传递到 `AdRequest` 构建器。 ||
|| `BannerAdSize` | `stickySize` | 已移除。 使用 `BannerAdSize.sticky`。 ||
|| ^ | `inlineSize` | 已移除。 使用 `BannerAdSize.inline`。 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   val banner = findViewById<R.id.banner>(BannerAdView)
   val stickySize = BannerAdSize.stickySize(this, screenWidth)
   val inlineSizeSize = BannerAdSize.inlineSize(this, screenWidth, 300)
   banner.setAdUnitId("R-M-XXXXX-YY")
   banner.setAdSize(stickySize)
   banner.loadAd(AdRequest.Builder().build())
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   val banner = findViewById<R.id.banner>(BannerAdView)
   val stickySize = BannerAdSize.sticky(this, screenWidth)
   val inlineSizeSize = BannerAdSize.inline(this, screenWidth, 300)
   banner.setAdSize(stickySize)
   banner.loadAd(AdRequest.Builder("R-M-XXXXX-YY").build())
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAd() {
       BannerAdView banner = findViewById(R.id.banner);
       BannerAdSize stickySize = BannerAdSize.stickySize(this, screenWidth);
       BannerAdSize inlineSizeSize = BannerAdSize.inlineSize(this, screenWidth, 300);
       banner.setAdUnitId("R-M-XXXXX-YY");
       banner.setAdSize(stickySize);
       banner.loadAd(new AdRequest.Builder().build());
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAd() {
       BannerAdView banner = findViewById(R.id.banner);
       BannerAdSize stickySize = BannerAdSize.sticky(this, screenWidth);
       BannerAdSize inlineSizeSize = BannerAdSize.inline(this, screenWidth, 300);
       banner.setAdSize(stickySize);
       banner.loadAd(new AdRequest.Builder("R-M-XXXXX-YY").build());
   }
   ```
   ||
   |#

{% endlist %}

### 5. AdInfo API 变更

我们已将广告创意数据的检索方法更改为属性，并移除了附加信息：

#|
|| **类** | **方法/字段** | **状态** ||
|| `BannerAdView`、`InsterstitialAd`、`RewardedAd`、`AppOpenAd`、`NativeAd` | `info` | 已移除。 使用 `adInfo` ||
|| ^ | `adAttributes` | 已移除。 使用 `adInfo` ||
|| `NativeAd` | `creativeId` | 已移除。 使用 `Creative.creativeId`。 ||
|| ^ | `campaignId` | 已移除。 使用 `Creative.campaignId`。 ||
|| `AdInfo` | `data` | 已移除 ||
|| ^ | `adSize` | 已移除 ||
|| ^ | `creatives` | 已添加 ||
|| ^ | `extraData` | 已添加 ||
|| ^ | `partnerText` | 已添加 ||
|| `Creative` | `placeId` | 已添加 ||
|| ^ | `offerId` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   // BannerAdView
   val extraData = banner.info
   val adUnitId = banner.adInfo.adUnitId
   val extraData2 = banner.adInfo.data
   val width = banner.adInfo.adSize?.width
   val height = banner.adInfo.adSize?.height
   val creativeId = banner.adInfo.creatives.first().creativeId
   val campaignId = banner.adInfo.creatives.first().campaignId
   val creativeId2 = banner.adAttributes.first().bannerId
   val campaignId2 = banner.adAttributes.first().campaignId
   val placeId = banner.adAttributes.first().placeId

   // InterstitialAd, RewardedAd, AppOpenAd
   val extraData = fullscreenAd.info.data
   val adUnitId = fullscreenAd.info.adUnitId
   val width = fullscreenAd.info.adSize?.width
   val height = fullscreenAd.info.adSize?.height
   val creativeId = fullscreenAd.info.creatives.first().creativeId
   val campaignId = fullscreenAd.info.creatives.first().campaignId
   val creativeId2 = fullscreenAd.adAttributes.first().bannerId
   val campaignId2 = fullscreenAd.adAttributes.first().campaignId
   val placeId = fullscreenAd.adAttributes.first().placeId

   // NativeAd
   val extraData = nativeAd.info
   val creativeId = nativeAd.creativeId
   val campaignId = nativeAd.campaignId
   val creativeId2 = nativeAd.adAttributes?.bannerId
   val campaignId2 = nativeAd.adAttributes?.campaignId
   val placeId = nativeAd.adAttributes?.placeId
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   // BannerAdView
   val extraData = banner.adInfo.extraData
   val partnerText = banner.adInfo.partnerText
   val creativeId = banner.adInfo.creatives.first().creativeId
   val campaignId = banner.adInfo.creatives.first().campaignId
   val placeId = banner.adInfo.creatives.first().placeId
   val adUnitId = banner.adInfo.adUnitId
   val width = banner.adSize?.width
   val height = banner.adSize?.height

   // InterstitialAd, RewardedAd, AppOpenAd
   val extraData = fullscreenAd.adInfo.extraData
   val partnerText = fullscreenAd.adInfo.partnerText
   val adUnitId = fullscreenAd.adInfo.adUnitId
   val creativeId = fullscreenAd.adInfo.creatives.first().creativeId
   val campaignId = fullscreenAd.adInfo.creatives.first().campaignId
   val placeId = fullscreenAd.adInfo.creatives.first().placeId

   // NativeAd
   val extraData = nativeAd.adInfo.extraData
   val partnerText = nativeAd.adInfo.partnerText
   val adUnitId = nativeAd.adInfo.adUnitId
   val creativeId = nativeAd.adInfo.creatives.first().creativeId
   val campaignId = nativeAd.adInfo.creatives.first().campaignId
   val placeId = nativeAd.adInfo.creatives.first().placeId
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   // BannerAdView
   String extraData = banner.getInfo();
   String adUnitId = banner.getAdInfo().getAdUnitId();
   String extraData2 = banner.getAdInfo().getData();
   int width = banner.getAdInfo().getAdSize().getWidth();
   int height = banner.getAdInfo().getAdSize().getHeight();
   String creativeId = banner.getAdInfo().getCreatives().get(0).getCreativeId();
   String campaignId = banner.getAdInfo().getCreatives().get(0).getCampaignId();
   String creativeId2 = banner.getAdAttributes().get(0).getBannerId();
   String campaignId2 = banner.getAdAttributes().get(0).getCampaignId();
   String placeId = banner.getAdAttributes().get(0).getPlaceId();

   // InterstitialAd, RewardedAD, AppOpenAd
   String extraData = fullscreenAd.getInfo().getData();
   String adUnitId = fullscreenAd.getInfo().getAdUnitId();
   int width = fullscreenAd.getInfo().getAdSize().getWidth();
   int height = fullscreenAd.getInfo().getAdSize().getHeight();
   String creativeId = fullscreenAd.getInfo().getCreatives().get(0).getCreativeId();
   String campaignId = fullscreenAd.getInfo().getCreatives().get(0).getCampaignId();
   String creativeId2 = fullscreenAd.getAdAttributes().get(0).getBannerId();
   String campaignId2 = fullscreenAd.getAdAttributes().get(0).getCampaignId();
   String placeId = fullscreenAd.getAdAttributes().get(0).getPlaceId();

   // NativeAd
   String extraData = nativeAd.getInfo();
   String creativeId = nativeAd.getCreativeId();
   String campaignId = nativeAd.getCampaignId();
   String creativeId2 = nativeAd.getAdAttributes().getBannerId();
   String campaignId2 = nativeAd.getAdAttributes().getCampaignId();
   String placeId = nativeAd.getAdAttributes().getPlaceId();
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   // BannerAdView
   String extraData = banner.getAdInfo().getExtraData();
   String partnerText = banner.getAdInfo().getPartnerText();
   String creativeId = banner.getAdInfo().getCreatives().get(0).getCreativeId();
   String campaignId = banner.getAdInfo().getCreatives().get(0).getCampaignId();
   String placeId = banner.getAdInfo().getCreatives().get(0).getPlaceId();
   String adUnitId = banner.getAdInfo().getAdUnitId();
   int width = banner.getAdSize().getWidth();
   int height = banner.getAdSize().getHeight();

   // InterstitialAd, RewardedAd, AppOpenAd
   String extraData = fullscreenAd.getAdInfo().getExtraData();
   String partnerText = fullscreenAd.getAdInfo().getPartnerText();
   String adUnitId = fullscreenAd.getAdInfo().getAdUnitId();
   String creativeId = fullscreenAd.getAdInfo().getCreatives().get(0).getCreativeId();
   String campaignId = fullscreenAd.getAdInfo().getCreatives().get(0).getCampaignId();
   String placeId = fullscreenAd.getAdInfo().getCreatives().get(0).getPlaceId();

   // NativeAd
   String extraData = nativeAd.getAdInfo().getExtraData();
   String partnerText = nativeAd.getAdInfo().getPartnerText();
   String adUnitId = nativeAd.getAdInfo().getAdUnitId();
   String creativeId = nativeAd.getAdInfo().getCreatives().get(0).getCreativeId();
   String campaignId = nativeAd.getAdInfo().getCreatives().get(0).getCampaignId();
   String placeId = nativeAd.getAdInfo().getCreatives().get(0).getPlaceId();
   ```
   ||
   |#

{% endlist %}


### 6. 原生广告 API 变更

- `NativeAd.bindNativeAd` 和 `SliderAd.bindSliderAd()` 方法现在返回 `AdBindingResult`，不再抛出异常。
- `warning` 字段类型已从 `String?` 更改为 `NativeAdWarning?`。 为了遵守联邦“广告法”，除了 `warning` 素材的内容之外，新类还提供 `warning` 素材的最低要求大小占总广告区域的百分比。
- `NativeAdMedia` 类现提供 `hasVideo` 字段，用于指示所选广告是否包含视频创意。

#|
|| **类** | **状态** ||
|| `AdBindingResult` |  已添加 ||
|| `NativeAdWarning` |  已添加 ||
|#

#|
|| **类** | **方法/字段** | **状态** ||
|| `NativeAd` | `bindNativeAd` | 该方法现在返回 `AdBindingResult` 值。 不再抛出异常。 ||
|| `SliderAd` | `bindSliderAd` | 该方法现在返回 `AdBindingResult` 值。 不再抛出异常。 ||
|| `NativeAdAssets` | `warning` | 类型已更改：`String` → `NativeAdWarning` ||
|| `NativeAdWarning` | `value` | 已添加 ||
|| ^ | `minimumRequiredArea` | 已添加 ||
|| `NativeAdMedia` | `hasVideo` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   val warning = nativeAd.adAssets.warning
   try {
       nativeAd.bindNativeAd(binder)
   } catch (e: NativeAdException) {
       val message = e.message
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   val warningAsset = nativeAd.adAssets.warning
   val warning = warningAsset?.value
   val warningMinArea = warningAsset?.minimumRequiredArea
   val hasVideo = nativeAd.adAssets.media?.hasVideo
   when (val result = nativeAd.bindNativeAd(binder)) {
       is AdBindingResult.Failure -> {
           val missingAssetName = result.missingAssetName
           val message = result.exception.message
       }
       AdBindingResult.Success -> Unit
   }
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void bindAd(NativeAd nativeAd) {
       String warning = nativeAd.getAdAssets().getWarning();
       try {
           nativeAd.bindNativeAd(binder);
       } catch (NativeAdException e) {
           String message = e.getMessage();
       }
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void bindNativeAd(NativeAd nativeAd) {
       NativeAdWarning warningAsset = nativeAd.getAdAssets().getWarning();
       String warning = warningAsset.getValue();
       float minWarningArea = warningAsset.getMinimumRequiredArea();
       boolean hasVideo = nativeAd.getAdAssets().getMedia().getHasVideo();
       AdBindingResult result = nativeAd.bindNativeAd(binder);
       if (result instanceof AdBindingResult.Failure) {
           String missingAssetName = ((AdBindingResult.Failure) result).getMissingAssetName();
           String message = ((AdBindingResult.Failure) result).getException().getMessage();
       }
   }
   ```
   ||
   |#

{% endlist %}

### 6.1 原生广告模板 API

通过模板集成原生广告的工具已被移除。 使用标准原生广告
素材进行集成。

#|
|| **类** | **状态** ||
|| `NativeBannerView` | 已移除 ||
|| `SizeConstraint` | ^ ||
|| `HorizontalOffset` | ^ ||
|| `NativeTemplateAppearance` | ^ ||
|| `TextAppearance` | ^ ||
|| `BannerAppearance` | ^ ||
|| `ButtonAppearance` | ^ ||
|| `RatingAppearance` | ^ ||
|#

### 7. 广告对象的某些回调方法已被移除

- `ClosableBannerAdEventListener` 和 `ClosableNativeAdEventListener` 界面已被移除。
- 方法 `onLeftApplication` 和 `onReturnToApplication` 已被移除。

#|
|| **类** | **状态** ||
|| `ClosableBannerAdEventListener` |  已移除 ||
|| `ClosableNativeAdEventListener` |  已移除 ||
|#

#|
|| **类** | **方法** | **状态** ||
|| `BannerAdEventListener`, `NativeAdEventListener` | `onLeftApplication` | 已移除 ||
|| ^ | `onReturnToApplication` | 已移除 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   bannerAd?.setBannerAdEventListener(object : ClosableBannerAdEventListener {
       override fun closeBannerAd() { /* ... */ }
       override fun onAdClicked() { /* ... */ }
       override fun onAdFailedToLoad(error: AdRequestError) { /* ... */ }
       override fun onAdLoaded() { /* ... */ }
       override fun onImpression(impressionData: ImpressionData?) { /* ... */ }
       override fun onLeftApplication() { /* ... */ }
       override fun onReturnedToApplication() { /* ... */ }
   })
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   // ClosableAdEventListener 以及
   // onAdClosed 回调不再可用
   bannerAdView?.setBannerAdEventListener(object : BannerAdEventListener {
       override fun onAdClicked() { /* ... */ }
       override fun onAdFailedToLoad(error: AdRequestError) { /* ... */ }
       override fun onAdLoaded() { /* ... */ }
       override fun onImpression(impressionData: ImpressionData?) { /* ... */ }
   })
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void setEventListener(BannerAdView bannerView) {
       bannerView.setBannerAdEventListener(
       new ClosableBannerAdEventListener() {
               @Override
               public void closeBannerAd() { /* ... */ }
               @Override
               public void onAdLoaded() { /* ... */ }
               @Override
               public void onAdFailedToLoad(@NotNull AdRequestError adRequestError) { /* ... */ }
               @Override
               public void onAdClicked() { /* ... */ }
               @Override
               public void onLeftApplication() { /* ... */ }
               @Override
               public void onReturnedToApplication() { /* ... */ }
               @Override
               public void onImpression(@Nullable ImpressionData impressionData) { /* ... */ }
           }
       );
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void setEventListener(BannerAdView bannerView) {
   // ClosableAdEventListener 以及
   // onAdClosed 回调不再可用
       bannerView.setBannerAdEventListener(
           new BannerAdEventListener() {
               @Override
               public void onAdLoaded() { /* ... */ }
               @Override
               public void onAdFailedToLoad(@NotNull AdRequestError adRequestError) { /* ... */ }
               @Override
               public void onAdClicked() { /* ... */ }
               @Override
               public void onImpression(@Nullable ImpressionData impressionData) { /* ... */ }
           }
       );
   }
   ```
   ||
   |#

{% endlist %}

### 8. 主 SDK 类变更

- 主 SDK 类已重命名为 `YandexAds`。
- 我们也重命名了一些隐私设置配置方法。

#|
|| **类** |  **状态** ||
|| `YandexAds` |  已添加 ||
|| `MobileAds` | 已移除。 使用 `YandexAds` ||
|#

#|
|| **类** | **方法** | **状态** ||
|| `MobileAds` | `setAgeRestrictedUser(Boolean)` | 已移除。 使用 `YandexAds.setAgeRestricted(Boolean)`。 ||
|| ^ | `setLocationConsent(Boolean)` | 已移除。 使用 `YandexAds.setLocationTracking(Boolean)`。 ||
|| `YandexAds` | `setAgeRestricted(Boolean)` | 已添加 ||
|| ^ | `setLocationTracking(Boolean)` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   import com.yandex.mobile.ads.common.MobileAds

   MobileAds.setUserConsent(true)
   MobileAds.setAgeRestrictedUser(false)
   MobileAds.setLocationConsent(true)
   MobileAds.initialize(context) { /* ... */ }
   MobileAds.enableDebugErrorIndicator(true)
   MobileAds.enableLogging(true)
   MobileAds.setAppAdAnalyticsReporting(true)
   MobileAds.showDebugPanel(this)
   MobileAds.libraryVersion
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   import com.yandex.mobile.ads.common.YandexAds

   YandexAds.setUserConsent(true)
   YandexAds.setAgeRestricted(false)
   YandexAds.setLocationTracking(true)
   YandexAds.initialize(context) { /* ... */ }
   YandexAds.enableDebugErrorIndicator(true)
   YandexAds.enableLogging(true)
   YandexAds.setAppAdAnalyticsReporting(true)
   YandexAds.showDebugPanel(this)
   YandexAds.libraryVersion
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   import com.yandex.mobile.ads.common.MobileAds;

   void initSdk() {
       MobileAds.setUserConsent(true);
       MobileAds.setAgeRestrictedUser(false);
       MobileAds.setLocationConsent(true);
       MobileAds.initialize(this, () -> { /* ... */ });
       MobileAds.getLibraryVersion();
       MobileAds.enableDebugErrorIndicator(true);
       MobileAds.enableLogging(true);
       MobileAds.setAppAdAnalyticsReporting(true);
       MobileAds.showDebugPanel(this);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   import com.yandex.mobile.ads.common.YandexAds;

   void initSdk() {
       YandexAds.setUserConsent(true);
       YandexAds.setAgeRestricted(false);
       YandexAds.setLocationTracking(true);
       YandexAds.initialize(this, () -> { /* ... */ });
       YandexAds.getLibraryVersion();
       YandexAds.enableDebugErrorIndicator(true);
       YandexAds.enableLogging(true);
       YandexAds.setAppAdAnalyticsReporting(true);
       YandexAds.showDebugPanel(this);
   }
   ```
   ||
   |#

{% endlist %}

## 视频插播广告 API 变更

### 1. 软件包和依赖项结构变更

为匹配新的 SDK 结构，已将核心类重命名。

#|
|| **类** | **状态** ||
|| `com.yandex.mobile.ads.instream.InstreamAdBinder` | 已移至 `com.yandex.mobile.ads.instream.binder.InstreamAdBinder` ||
|| `com.yandex.mobile.ads.instream.InstreamAdRequestConfiguration` | 已重命名为 `com.yandex.mobile.ads.instream.InstreamAdRequest` ||
|| `com.yandex.mobile.ads.instream.InstreamAdBreak` | 已重命名为 `com.yandex.mobile.ads.instream.adbreak.AdBreakData` ||
|| `com.yandex.mobile.ads.instream.inroll.Inroll`、`com.yandex.mobile.ads.instream.pauseroll.Pauseroll` | 已替换为 `com.yandex.mobile.ads.instream.adbreak.InstreamAdBreak` ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   import com.yandex.mobile.ads.instream.InstreamAdBinder
   import com.yandex.mobile.ads.instream.InstreamAdRequestConfiguration
   import com.yandex.mobile.ads.instream.InstreamAdBreak
   import com.yandex.mobile.ads.instream.inroll.Inroll
   import com.yandex.mobile.ads.instream.pauseroll.Pauseroll
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   import com.yandex.mobile.ads.instream.binder.InstreamAdBinder
   import com.yandex.mobile.ads.instream.InstreamAdRequest
   import com.yandex.mobile.ads.instream.adbreak.AdBreakData
   import com.yandex.mobile.ads.instream.adbreak.InstreamAdBreak
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   import com.yandex.mobile.ads.instream.InstreamAdBinder;
   import com.yandex.mobile.ads.instream.InstreamAdRequestConfiguration;
   import com.yandex.mobile.ads.instream.InstreamAdBreak;
   import com.yandex.mobile.ads.instream.inroll.Inroll;
   import com.yandex.mobile.ads.instream.pauseroll.Pauseroll;
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   import com.yandex.mobile.ads.instream.binder.InstreamAdBinder;
   import com.yandex.mobile.ads.instream.InstreamAdRequest;
   import com.yandex.mobile.ads.instream.adbreak.AdBreakData;
   import com.yandex.mobile.ads.instream.adbreak.InstreamAdBreak;
   ```
   ||
   |#

{% endlist %}

### 2. AdRequest 变更

`InstreamAdRequestConfiguration` 类已重命名为 `InstreamAdRequest`。

#|
|| **类** | **状态** ||
|| `InstreamAdRequestConfiguration` | 已移除。 使用 `InstreamAdRequest` ||
|| `InstreamAdRequest` | 已添加 ||
|| `InstreamAdBreakRequest` | 已添加 ||
|#


#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   val loader = InstreamAdLoader(this)
   val config = InstreamAdRequestConfiguration.Builder("XXXXXX").build()
   loader.loadInstreamAd(this, config)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   val loader = InstreamAdLoader(this)
   val config = InstreamAdRequest.Builder("XXXXXX").build()
   loader.loadInstreamAd(this, config)
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAd() {
       InstreamAdLoader loader = new InstreamAdLoader(this);
       InstreamAdRequestConfiguration config = new InstreamAdRequestConfiguration.Builder("XXXXXX").build();
       loader.loadInstreamAd(this, config);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAd() {
       InstreamAdLoader loader = new InstreamAdLoader(this);
       InstreamAdRequest config = new InstreamAdRequest.Builder("XXXXXX").build();
       loader.loadInstreamAd(this, config);
   }
   ```
   ||
   |#

{% endlist %}

### 3. 广告加载 API 变更

- 注册回调方法和广告加载监听器已更新。
- API 现提供 `InstreamAdBreakLoader` 类，用于加载广告插播。
- `onInstreamAdFailedToLoad` 方法签名已更改：现在传递的是 `InstreamAdRequestError` 对象，而不是 `reason` 字符串。

#|
|| **类**  | **状态** ||
|| `InstreamAdBreakLoadListener`  | 已添加 ||
|| `InstreamAdBreakLoader` | 已添加 ||
|#

#|
|| **类** | **方法** | **状态** ||
|| `InstreamAdLoader` | `setInstreamAdLoadListener(InstreamAdLoadListener)` | 已移除。 将 `InstreamAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAd(InstreamAdRequestConfiguration)` | 已移除。 将 `InstreamAdLoadListener` 传递到 `loadAd` 方法。 ||
|| ^ | `loadAd(InstreamAdRequest, InstreamAdLoadListener)` | 已移除。 将 `InstreamAdLoadListener` 传递到 `loadAd` 方法。 ||
|| `InstreamAdLoadListener` | `onInstreamAdFailedToLoad(String)` | 已移除。 使用 `onInstreamAdFailedToLoad(InstreamAdRequestError)`。 ||
|| ^ | `onInstreamAdFailedToLoad(InstreamAdRequestError)` | 已添加 ||
|| `InstreamAdBreakLoader` | `loadAd(InstreamAdBreakRequest, InstreamAdBreakLoadListener)` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   val instreamAdLoader = InstreamAdLoader(this)
   instreamAdLoader.setInstreamAdLoadListener(object : InstreamAdLoadListener {
       override fun onInstreamAdLoaded(instreamAd: InstreamAd) {
           // ...
       }

       override fun onInstreamAdFailedToLoad(reason: String) {
           println("Instream ad failed to load: $reason")
       }
   })
   val config = InstreamAdRequestConfiguration.Builder("XXXXXX").build()
   instreamAdLoader.loadInstreamAd(this, config)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   val instreamAdLoader = InstreamAdLoader(this)
   val config = InstreamAdRequest.Builder("XXXXXX").build()
   instreamAdLoader.loadAd(config, object : InstreamAdLoadListener {
       override fun onInstreamAdLoaded(instreamAd: InstreamAd) {
           // ...
       }

       override fun onInstreamAdFailedToLoad(error: InstreamAdRequestError) {
           println("Instream ad failed to load: ${error.reason}")
       }
   })
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadInstreamAd() {
       InstreamAdLoader instreamAdLoader = new InstreamAdLoader(this);
       instreamAdLoader.setInstreamAdLoadListener(new InstreamAdLoadListener() {
           @Override
           public void onInstreamAdLoaded(InstreamAd instreamAd) {
               // ...
           }

           @Override
           public void onInstreamAdFailedToLoad(String reason) {
               System.out.println("Instream ad failed to load: " + reason);
           }
       });
       InstreamAdRequestConfiguration config = new InstreamAdRequestConfiguration.Builder("XXXXXX").build();
       instreamAdLoader.loadInstreamAd(this, config);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadInstreamAd() {
       InstreamAdLoader instreamAdLoader = new InstreamAdLoader(this);
       InstreamAdRequest config = new InstreamAdRequest.Builder("XXXXXX").build();
       instreamAdLoader.loadAd(config, new InstreamAdLoadListener() {
           @Override
           public void onInstreamAdLoaded(InstreamAd instreamAd) {
               // ...
           }

           @Override
           public void onInstreamAdFailedToLoad(InstreamAdRequestError error) {
               System.out.println("Instream ad failed to load: " + error.getReason());
           }
       });
   }
   ```
   ||
   |#

{% endlist %}

### 3.1 Kotlin 协程支持

我们已将广告加载方法的 `suspend` 重载添加到 `InstreamAdLoader` 和 `InstreamAdBreakAdLoader` 中。

#|
|| **类** | **方法** | **状态** ||
|| `InstreamAdLoader` | `suspend fun loadAd(InstreamAdRequest): InstreamAdLoadResult` | 已添加 ||
|| `InstreamAdBreakLoader` | `suspend fun loadAd(InstreamAdBreakRequest): InstreamAdBreakLoadResult` | 已添加 ||
|#

#### 例如

```kotlin
lifecycleScope.launch {
    val instreamAdLoader = InstreamAdLoader(applicationContext)
    when(val result = instreamAdLoader.loadAd(InstreamAdRequest.Builder("XXXXXX").build())) {
        is InstreamAdLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is InstreamAdLoadResult.Success -> TODO("Show instream ad: ${result.ad}")
    }

    val adBreakLoader = InstreamAdBreakLoader(applicationContext)
    when (val result = adBreakLoader.loadAd(InstreamAdBreakRequest.Builder("XXXXXX", "YY").build())) {
        is InstreamAdBreakLoadResult.Failure -> TODO("Handle error: ${result.error.description}")
        is InstreamAdBreakLoadResult.Success -> TODO("Show adBreak : ${result.adBreak}")
    }
}
```

### 4. 使用内贴片广告和暂停时广告

- 广告插播的管理逻辑变得更灵活了。
- 专门的队列提供者 `InrollQueueProvider` 和 `PauserollQueueProvider` 已被移除。 广告插播现在可以直接从 `InstreamAd` 对象访问，可按类型进行筛选。

{% note info "" %}

如果您通过 `InstreamAdBinder` 使用自动渲染，请从 `instreamAdBreaks` 集合中仅选择 `INROLL` 和 `PAUSEROLL` 广告插播。

{% endnote %}

#|
|| **类** | **状态** ||
|| `InrollQueueProvider` | 已移除。 使用按 `InstreamAdBreakType.INROLL` 筛选的 `instreamAd.instreamAdBreaks`。 ||
|| `PauserollQueueProvider` | 已移除。 使用按 `InstreamAdBreakType.PAUSEROLL` 筛选的 `instreamAd.instreamAdBreaks`。 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   // 1. 从已加载广告中获取内贴片广告队列
   val inrollQueueProvider = InrollQueueProvider(context, instreamAd)
   val instreamAdBreakQueue = inrollQueueProvider.queue

   // 2. 准备特定广告插播
   val currentInroll = instreamAdBreakQueue.poll()
   currentInroll?.setListener(object : InstreamAdBreakEventListener {
       override fun onInstreamAdBreakPrepared() {
           // 3. 显示准备好的广告插播
           currentInroll.play(instreamAdView)
       }
       // ... other listener methods
   })
   currentInroll?.prepare(instreamAdPlayer)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   // 1. 直接从 InstreamAd 获取所有广告插播的列表
   val inrolls = instreamAd.instreamAdBreaks.filter {
       it.adBreakData.type == InstreamAdBreakType.INROLL
   }

   // 2. 准备并显示
   val inrollIndex = 0 // 自行管理索引
   val currentInroll = inrolls.getOrNull(inrollIndex)

   currentInroll?.setListener(object : InstreamAdBreakEventListener {
       override fun onInstreamAdBreakPrepared() {
           // 3. 显示准备好的广告插播
           currentInroll.play(instreamAdView)
       }
   })
   currentInroll?.prepare(instreamAdPlayer)
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAdBreak() {
   // 1. 从已加载广告中获取内贴片广告队列
       InrollQueueProvider inrollQueueProvider = new InrollQueueProvider(context, instreamAd);
       Queue<Inroll> instreamAdBreakQueue = inrollQueueProvider.getQueue();

   // 2. 准备特定广告插播
       Inroll currentInroll = instreamAdBreakQueue.poll();
       if (currentInroll != null) {
           currentInroll.setListener(new InstreamAdBreakEventListener() {
               @Override
               public void onInstreamAdBreakPrepared() {
                   // 3. 显示准备好的广告插播
                   currentInroll.play(instreamAdView);
               }
               // ... other listener methods
           });
           currentInroll.prepare(instreamAdPlayer);
       }
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAdBreak() {
       // 1. 直接从 InstreamAd 获取所有广告插播的列表
       List<InstreamAdBreak> inrolls = new ArrayList<>();
       for (InstreamAdBreak adBreak : instreamAd.getInstreamAdBreaks()) {
           if (adBreak.getAdBreakData().getType() == InstreamAdBreakType.INROLL) {
               inrolls.add(adBreak);
           }
       }

       // 2. 准备并显示
       int inrollIndex = 0; // 自行管理索引
       InstreamAdBreak currentInroll = inrollIndex < inrolls.size() ? inrolls.get(inrollIndex) : null;

       if (currentInroll != null) {
           currentInroll.setListener(new InstreamAdBreakEventListener() {
               @Override
               public void onInstreamAdBreakPrepared() {
                   // 3. 显示准备好的广告插播
                   currentInroll.play(instreamAdView);
               }
           });
           currentInroll.prepare(instreamAdPlayer);
       }
   }
   ```
   ||
   |#

{% endlist %}

### 5. 默认播放器

现在可以选择传递视频渲染的播放器信息。 如果传递了 `null`，SDK 将完全控制视频渲染。

#|
|| **类** | **方法** | **状态** ||
|| `InstreamAdBinder` | 构建器 | `instreamAdPlayer` 参数现为可选参数，可以设置为 `null` ||
|| `InstreamAdBreak` | `prepare(instreamAdPlayer)` | 已移除。 使用无参数的 `prepare()` ||
|| ^ | `prepare()` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   // 自动启动 (InstreamAdBinder)
   val instreamAdBinder = InstreamAdBinder(
       context,
       instreamAd,
       instreamAdPlayer, // 需要播放器
       contentPlayer
   )

   // 手动启动 (InstreamAdBreak)
   val adBreak: InstreamAdBreak
   adBreak.prepare(instreamAdPlayer)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   // Automatic launch (InstreamAdBinder)
   // Default ad player is used when the parameter is omitted
   val instreamAdBinder = InstreamAdBinder(
       context,
       instreamAd,
       contentPlayer
   ) 
   // Manual launch (InstreamAdBreak)
   val adBreak: InstreamAdBreak
   adBreak.prepare()
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void showAd() {
       // 自动启动 (InstreamAdBinder)
       InstreamAdBinder instreamAdBinder = new InstreamAdBinder(
               context,
               instreamAd,
               instreamAdPlayer, // 需要播放器
               contentPlayer
       );

       // 手动启动 (InstreamAdBreak)
       InstreamAdBreak adBreak;
       adBreak.prepare(instreamAdPlayer);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void showAd() {
       // 自动启动 (InstreamAdBinder)
       // Default ad player is used when the parameter is omitted
       InstreamAdBinder instreamAdBinder = new InstreamAdBinder(
               context,
               instreamAd,
               contentPlayer
       );

       // 手动启动 (InstreamAdBreak)
       InstreamAdBreak adBreak;
       adBreak.prepare();
   }
   ```
   ||
   |#

{% endlist %}

### 6. InstreamAdPlayer 界面变更

`InstreamAdPlayer` 界面已更新，现提供用于优化视频格式选择的 `supportedMimeTypes` 属性和用于在视频顶部正确定位广告元素的 `bindPlayerView` 方法。

#|
|| **类** | **方法** | **状态** ||
|| `InstreamAdPlayer` | `supportedMimeTypes: List<String>` | 已添加。 允许 SDK 选择最适合的视频格式，例如 DASH，而非 MP4。 ||
|| ^ | `bindPlayerView(container: FrameLayout)` | 已添加。 `videoPlayerView` 必须放入提供的容器内，并设置为填满整个空间。 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   class InstreamAdPlayerImpl : InstreamAdPlayer {
       // ... methods（prepareAd、playAd、pauseAd 等）
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   class InstreamAdPlayerImpl : InstreamAdPlayer {

       // 1. 播放器支持的 MIME 类型列表
       override val supportedMimeTypes: List<String>
           get() = listOf(InstreamAdMimeTypes.MP4, InstreamAdMimeTypes.WEBM)

       // 2. videoPlayerView 必须放入容器内并设置为填满整个空间
       override fun bindPlayerView(container: FrameLayout) {
           container.addView(playerView)
       }

       // ... other methods（prepareAd、playAd、pauseAd 等）
   }
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   public class InstreamAdPlayerImpl implements InstreamAdPlayer {
       // ... 方法（prepareAd、playAd、pauseAd 等）
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   public class InstreamAdPlayerImpl implements InstreamAdPlayer {

       // 1. 播放器支持的 MIME 类型列表
       @Override
       public List<String> getSupportedMimeTypes() {
           return Arrays.asList(InstreamAdMimeTypes.MP4, InstreamAdMimeTypes.WEBM);
       }

       // 2. videoPlayerView 必须放入容器内并设置为填满整个空间
       @Override
       public void bindPlayerView(FrameLayout container) {
           container.addView(playerView);
       }

       // ... 其他方法（prepareAd、playAd、pauseAd 等）
   }
   ```
   ||
   |#

{% endlist %}

## 聚合网络 API 变更

### 1. 新增用于传递聚合网络数据的 API

聚合适配器识别现在是单独方法的一部分。

#|
|| **类** | **状态** ||
|| `AdapterIdentity` | 已添加 ||
|#

#|
|| **类** | **方法** | **状态** ||
|| `YandexAds` | `setAdapterIdentity(AdapterIdentity)` | 已添加。 在调用 `YandexAds.initialize` 之前调用此方法，而不是在广告请求中将适配器数据作为附加参数传递。 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

   #|
   || **SDK 7** ||
   ||
   ```kotlin
   YandexAds.initialize(context, listener)

   val parameters = mapOf(
       "adapter_network_name" to "AdNetwork",
       "adapter_network_version" to "1.2.3",
       "adapter_version" to "1.0.0"
   )

   val adRequest = AdRequest.Builder()
       .setParameters(parameters)
       .build()

   bannerAd.loadAd(adRequest)
   ```
   ||
   || **SDK 8** ||
   ||
   ```kotlin
   val identity = AdapterIdentity("AdNetwork", "1.0.0", "1.2.3")
   YandexAds.setAdapterIdentity(identity) // 在 initialize() 之前调用
   YandexAds.initialize(context, listener)

   // 无需传递附加参数
   val adRequest = AdRequest.Builder("R-M-XXXXX-YY").build()
   bannerAd.loadAd(adRequest)
   ```
   ||
   |#

- Java

   #|
   || **SDK 7** ||
   ||
   ```java
   void loadAd() {
       Map<String, String> parameters = new HashMap<>();
       parameters.put("adapter_network_name", "AdNetwork");
       parameters.put("adapter_network_version", "1.2.3");
       parameters.put("adapter_version", "1.0.0");

       AdRequest adRequest = new AdRequest.Builder()
               .setParameters(parameters)
               .build();

       bannerView.loadAd(adRequest);
   }
   ```
   ||
   || **SDK 8** ||
   ||
   ```java
   void loadAd() {
       AdapterIdentity adapterIdentity = new AdapterIdentity("AdNetwork", "1.0.0", "1.2.3");
       YandexAds.setAdapterIdentity(adapterIdentity); // 在 initialize() 之前调用
       YandexAds.initialize(this, () -> { /* ... */ });

       // 无需传递附加参数
       AdRequest adRequest = new AdRequest.Builder("R-M-XXXXX-YY").build();

       bannerView.loadAd(adRequest);
   }
   ```
   ||
   |#

{% endlist %}

### 2. 重命名并简化 BidderTokenRequest 类

- `BidderTokenLoader` 类现在提供构建器，并且 `loadBidderToken` 静态方法现已成为实例方法。
- `BidderTokenRequestConfiguration` 类已重命名为 `BidderTokenRequest`，并已更新。
- 要创建实例，请使用 `banner`、`interstitial`、`rewarded`、`appOpenAd` 和 `native` 工厂方法，而非使用 `Builder(AdType)`。

#|
|| **类** | **状态** ||
|| `BidderTokenRequestConfiguration` | 已移除。 使用 `BidderTokenRequest` ||
|| `BidderTokenRequestConfiguration.Builder` | 已移除。 在 `BidderTokenRequest` 中使用工厂方法 ||
|| `BidderTokenRequest` | 已添加 ||
|#

#|
|| **类** | **构建器/方法** | **状态** ||
|| `BidderTokenLoader` | `BidderTokenLoader(Context)` | 现提供构建器 ||
|| ^ | `loadBidderToken` | 已更新。 静态方法现已成为 `BidderTokenLoader` 类的实例方法 ||

|| `BidderTokenRequestConfiguration.Builder` | `setBannerAdSize(BannerAdSize)` | 已移除。 将 `BannerAdSize` 传递到 `BidderTokenRequest.banner(BannerAdSize)` 方法参数 ||
|| ^ | `setParameters(Map<String, String>)` | 已移除。 将这些参数传递到工厂方法的参数 ||
|| `BidderTokenRequest` | `banner(BannerAdSize)` | 已添加 ||
|| ^ | `banner(BannerAdSize, AdTargeting)` | 已添加 ||
|| ^ | `banner(BannerAdSize, AdTargeting, Map<String, String>)` | 已添加 ||
|| ^ | `interstitial()` | 已添加 ||
|| ^ | `interstitial(AdTargeting)` | 已添加 ||
|| ^ | `interstitial(AdTargeting, Map<String, String>)` | 已添加 ||
|| ^ | `rewarded()` | 已添加 ||
|| ^ | `rewarded(AdTargeting)` | 已添加 ||
|| ^ | `rewarded(AdTargeting, Map<String, String>)` | 已添加 ||
|| ^ | `appOpenAd()` | 已添加 ||
|| ^ | `appOpenAd(AdTargeting)` | 已添加 ||
|| ^ | `appOpenAd(AdTargeting, Map<String, String>)` | 已添加 ||
|| ^ | `native()` | 已添加 ||
|| ^ | `native(AdTargeting)` | 已添加 ||
|| ^ | `native(AdTargeting, Map<String, String>)` | 已添加 ||
|#

#### 示例

{% list tabs group=instructions %}

- Kotlin

  #|
  || **SDK 7** ||
  || 
  ```kotlin
  val bidderTokenRequest = BidderTokenRequestConfiguration.Builder(AdType.INTERSTITIAL)
      .setBannerAdSize(BannerAdSize.stickySize(this, screenWidth))
      .setParameters(mapOf("a" to "b"))
      .build()

  BidderTokenLoader.loadBidderToken(
      this,
      bidderTokenRequest,
      object : BidderTokenLoadListener { /* ... */ }
  )
  ``` 
  ||
  || **SDK 8** ||
  || 
  ```kotlin
  val bidderTokenLoader = BidderTokenLoader(this);
  bidderTokenLoader.loadBidderToken(
      BidderTokenRequest.banner(BannerAdSize.sticky(this, screenWidth), parameters = mapOf("a" to "b")),
      object : BidderTokenLoadListener { /* ... */ }
  )

  bidderTokenLoader.loadBidderToken(
      BidderTokenRequest.interstitial(),
      object : BidderTokenLoadListener { /* ... */ }
  )
  ``` 
  ||
  |#

- Java

  #|
  || **SDK 7** ||
  || 
  ```java
  void loadToken() {
      Map<String, String> parameters = new HashMap<>();
      parameters.put("a", "b");

      BidderTokenRequestConfiguration bidderTokenRequest =
              new BidderTokenRequestConfiguration.Builder(AdType.INTERSTITIAL)
                      .setBannerAdSize(BannerAdSize.stickySize(this, screenWidth))
                      .setParameters(parameters)
                      .build();

      BidderTokenLoader.loadBidderToken(
              this,
              bidderTokenRequest,
              new BidderTokenLoadListener() { /* ... */ }
      );
  }
  ``` 
  ||
  || **SDK 8** ||
  || 
  ```java
  void loadToken() {
      Map<String, String> parameters = new HashMap<>();
      parameters.put("a", "b");

      BidderTokenLoader bidderTokenLoader = new BidderTokenLoader(this);
      bidderTokenLoader.loadBidderToken(
              BidderTokenRequest.banner(BannerAdSize.inline(this, screenWidth), null, parameters),
              new BidderTokenLoadListener() { /* ... */ }
      );

      bidderTokenLoader.loadBidderToken(BidderTokenRequest.interstitial(),
              new BidderTokenLoadListener() { /* ... */ }
      );
  }
  ``` 
  ||
  |#

{% endlist %}

## Jetpack Compose 集成

已支持通过 Jetpack Compose 集成。示例见 Jetpack Compose 章节：

- [自适应 inline 横幅](https://ads.yandex.com/helpcenter/zh/dev/android/compose/adaptive-inline-banner.md)
- [自适应 sticky 横幅](https://ads.yandex.com/helpcenter/zh/dev/android/compose/adaptive-sticky-banner.md)
- [插屏广告](https://ads.yandex.com/helpcenter/zh/dev/android/compose/interstitial.md)
- [激励广告](https://ads.yandex.com/helpcenter/zh/dev/android/compose/rewarded.md)
- [开屏广告](https://ads.yandex.com/helpcenter/zh/dev/android/compose/app-open-ad.md)

## 使用 AI 工具迁移 {#ai}

为简化从 SDK 7.x 迁移到 8.x，可使用内置迁移技能的 AI 助手。

### 使用方法

1. **加载技能**

    迁移技能位于 [GitHub Yandex Ads SDK Android](https://github.com/yandexmobile/yandex-ads-sdk-android/tree/master/YandexMobileAdsExample/skills/migrate-yandex-ads-sdk-from-7-to-8)。

    - 适用于 Claude Desktop

        将技能文件夹复制到代理的 skills 目录，例如：

        ```bash
        cp -r Skills/migrate-yandex-ads-sdk-from-7-to-8 .claude/skills/
        ```

    - 适用于 Cursor IDE

        将技能文件夹复制到项目，并通过 `@` 引用 `SKILL.md`，例如：

        ```
        @migrate-yandex-ads-sdk-from-7-to-8/SKILL.md
        ```

    - 其他方式

        将 `SKILL.md` 及相关文件内容粘贴到 AI 对话中（可能超出消息长度限制）。

2. **使用提示词**

    加载技能后，在对话中使用如下提示：

    ```
    将我的项目从 Yandex Mobile Ads SDK 7.x 迁移到 8.x
    ```

{% note warning "" %}

请务必仔细审阅 AI 生成的变更。

技能有助于 AI 正确执行任务，但您仍需自行验证代理引入的每一处修改。AI 可能出错，代码必须经过人工复核。

{% endnote %}

## 环境要求

- **Gradle**：7.0 或更高版本
- **Android Gradle Plugin**：8.3.2 或更高版本
- **Android SDK**：21（Android 5.0）或更高版本
- **Kotlin**：1.9.0 或更高版本
- **Java**：8 或更高版本


