Banneranzeigen in scrollbaren Feeds wiederverwenden

Bei langen oder unendlichen Scrolllisten wie Newsfeeds oder Social-Media-Feeds kann das Erstellen einer Banneranzeige für jede Position zu hohem Speicherverbrauch und UI-Verzögerungen führen. Um die Leistung zu verbessern, sollten Sie Banner wiederverwenden, um einen kleinen Cache mit BannerAd-Instanzen mit fester Größe zu verwalten und Anzeigen, die nicht auf dem Bildschirm zu sehen sind, wiederzuverwenden, wenn der Nutzer scrollt.

Auf dieser Seite wird beschrieben, wie Sie die Größe eines Anzeigen-Cache festlegen, prüfen, ob eine BannerAd-Instanz außerhalb des Bildschirms liegt, und zwischengespeicherte Anzeigen neu Listenelementen zuweisen.

Das folgende Bild zeigt, wie eine Banneranzeige, die nicht auf dem Bildschirm zu sehen ist, in den Cache zurückkehrt und an einer Listenposition wiederverwendet wird, wenn der Nutzer scrollt:

Diagramm, das zeigt, wie eine Banneranzeige aus dem Bildschirm gescrollt wird, in den Anzeigen-Cache gelangt und unten im Feed auf dem Bildschirm wiederverwendet wird.

Vorbereitung

Bevor Sie fortfahren, verwenden Sie Inline-Anzeigen für adaptive Banner mit Scrollfunktion.

Zugewiesene Listenpositionen nachverfolgen

Wenn der Nutzer scrollt, werden durch das Banner-Recycling nur eine begrenzte Anzahl von BannerAd-Instanzen im Arbeitsspeicher behalten und zwischen den Listenpositionen verschoben.

Um zu wissen, welche Anzeige wiederverwendet werden soll, müssen Sie nachverfolgen, welche Listenposition jede Anzeige im Cache einnimmt.

Behalten Sie den folgenden Status in Ihrem Widget bei:

  • Ein Cache mit fester Größe von BannerAd-Instanzen. Die von Ihnen festgelegte Größe des Caches entspricht der maximalen Anzahl von Anzeigen, die gleichzeitig im Arbeitsspeicher gehalten werden.
  • Ein Anzeigenintervall, das bestimmt, wie oft eine Anzeige in der Liste erscheint.
  • Eine Map-Klasse, die jede BannerAd-Instanz mit der Listenposition verknüpft, die die Instanz einnimmt. Wenn Sie eine Anzeige wiederverwenden, aktualisieren Sie den Eintrag in dieser Map-Klasse, damit er auf die aktuelle Position verweist.
  • Eine Map-Klasse, in der das plattformbezogene AdSize-Objekt für jede geladene Anzeige gespeichert wird. Nachdem die Anzeige geladen wurde, sind die Höhen von adaptiven Inline-Bannern bekannt.

Im folgenden Beispiel werden die zugewiesenen Listenpositionen für jede Anzeige im Cache erfasst:

// Maximum number of banner ad instances kept in the cache.
static const int _cacheSize = 8;

// Spacing between banner ads. For example, index 0, 6, 12, and so on
// display ads.
static const int _adInterval = 6;

// The cache of allocated BannerAd instances.
final List<BannerAd> _banners = [];

// Maps each BannerAd instance to its currently assigned list item position.
final Map<BannerAd, int> _bannerPositions = {};

// Stores the platform-resolved size of each loaded banner ad.
final Map<BannerAd, AdSize> _bannerSizes = {};

Cache-Größe auswählen

Der Cache sollte größer sein als die maximale Anzahl von Anzeigen, die gleichzeitig auf dem Bildschirm erscheinen können. Wenn der Cache kleiner als diese Größe ist, ist die für die Wiederverwendung ausgewählte Anzeige oft noch sichtbar und Ihre App weist zusätzliche Anzeigen zu, anstatt die Anzeigen wiederzuverwenden.

So wählen Sie eine Größe aus:

  1. Schätzen Sie, wie viele Anzeigen gleichzeitig auf den Bildschirm passen, indem Sie die Höhe des Darstellungsbereichs durch die Höhe eines Anzeigenintervalls teilen.
  2. Platz für Anzeigen hinzufügen, die sich bei schnellem Scrollen noch lösen.
  3. Wenn Sie feststellen, dass Anzeigen, die für die Wiederverwendung ausgewählt wurden, weiterhin auf dem Bildschirm zu sehen sind, erhöhen Sie die Cachegröße.

Im Beispiel auf dieser Seite wird alle sechs Zeilen eine Anzeige eingeblendet und ein Cache von acht verwendet. In diesem Beispiel ist Platz für die wenigen Anzeigen, die gleichzeitig auf dem Bildschirm zu sehen sind.

Prüfen, ob eine Anzeige auf dem Bildschirm zu sehen ist

Alle Google Mobile Ads Flutter Plugin-Klassen, die Plattformansichten rendern, implementieren die AdWithView-Klasse und stellen einen isMounted-Getter bereit. Bevor Sie eine im Cache gespeicherte Anzeige einer Listenposition neu zuweisen, prüfen Sie mit dem isMounted-Getter, ob die Anzeige aus dem Bildschirm gescrollt wurde und sicher wiederverwendet werden kann.

Banneranzeige abrufen und wiederverwenden

Wenn in der Liste ein Banner für eine bestimmte Position angefordert wird, gehen Sie so vor:

  1. Die Anzeige, die dieser Position bereits zugewiesen ist, wird wiederverwendet, sofern vorhanden.
  2. Wenn der Cache nicht voll ist, fordern Sie eine Anzeige an.
  3. Wenn der Cache voll ist, wählen Sie eine im Cache gespeicherte Anzeige aus und prüfen Sie, ob der isMounted-Getter der false-Wert ist, bevor Sie die Anzeige neu zuweisen.
  4. Rufen Sie die Methode dispose() für jede Anzeige im Cache auf, wenn das Widget aus der Widget-Baumstruktur entfernt wird.

Im folgenden Beispiel wird eine Banneranzeige abgerufen und wiederverwendet:

BannerAd _getRecycledBannerAd(BuildContext context, int bannerPosition) {
  // 1. If an ad is already mapped to this position, reuse it.
  final BannerAd? existingBanner = _bannerPositions.entries
      .firstWhereOrNull((entry) => entry.value == bannerPosition)
      ?.key;
  if (existingBanner != null) {
    return existingBanner;
  }

  // 2. If the cache is not full, allocate a new ad instance.
  if (_banners.length < _cacheSize) {
    final BannerAd newBanner = _createBannerAd(context);
    _banners.add(newBanner);
    _bannerPositions[newBanner] = bannerPosition;
    return newBanner;
  }

  // 3. Select an existing ad from the cache using modulo arithmetic.
  final BannerAd targetBanner = _banners[bannerPosition % _cacheSize];

  // 4. Verify the ad is detached from the screen before recycling.
  if (targetBanner.isMounted) {
    // If still on screen during fast scrolls, allocate a temporary instance.
    return _createBannerAd(context);
  } else {
    // Safe to reuse: reassign to the new position.
    _bannerPositions[targetBanner] = bannerPosition;
    return targetBanner;
  }
}

Das vollständige Beispiel finden Sie unter Beispiel für Google Mobile Ads Flutter Plugin.