1

有时,即使在调用 dispose 之后,android 上的广告也不会被丢弃。由于横幅是叠加层,因此它覆盖了下一个屏幕。我的应用程序的用户报告说广告覆盖了他们的屏幕,因为前一个屏幕上的广告没有被处理掉。我已经看到了这个问题(https://github.com/FirebaseExtended/flutterfire/issues/96)并且我已经尝试处理它。以下是我处理一个广告单元的代码。

import 'package:firebase_admob/firebase_admob.dart';
import 'package:sampleapp/utilities/logger.dart';

enum AdUnitType { banner, interstitialAd }
enum AdUnitState { loading, loaded, showing, shown, disposing, dispose }

class AdUnitHandler {
  final String _adUnitId;
  final AdUnitType _adUnitType;
  final AdSize adSize;
  String adSizeString;
  MobileAd adUnit;
  bool _isLoaded;

  AdUnitHandler(
    this._adUnitId,
    this._adUnitType, {
    this.adSize = AdSize.banner,
  });

  Future<bool> load() async {
    await dispose();
    _isLoaded = false;
    switch (_adUnitType) {
      case AdUnitType.banner:
        adUnit = BannerAd(adUnitId: _adUnitId, size: adSize);
        adSizeString = adSize == AdSize.banner ? 'banner' : 'mediumRect';
        break;
      case AdUnitType.interstitialAd:
        adUnit = InterstitialAd(adUnitId: _adUnitId);
        adSizeString = 'interstitial';
        break;
    }
    adUnit.listener = (MobileAdEvent event) {
      Log.d('ad event $event');
      switch (event) {
        case MobileAdEvent.loaded:
          _isLoaded = true;
          break;
        case MobileAdEvent.failedToLoad:
        case MobileAdEvent.clicked:
        case MobileAdEvent.impression:
        case MobileAdEvent.opened:
        case MobileAdEvent.leftApplication:
          //do nothing
          break;
        case MobileAdEvent.closed:
          dispose();
          break;
      }
    };
    Log.d('Loading ad');
    return adUnit.load();
  }

  Future<bool> show() async {
    return adUnit?.show();
  }

  Future<void> dispose() async {
    if (adUnit == null) return;
    try {
      if (!_isLoaded) {
        int count = 0;
        await Future.doWhile(() async {
          if (await adUnit?.isLoaded()) {
            return false;
          }
          Log.d('ad is loading before dispose');
          await Future.delayed(Duration(seconds: 1));
          count++;
          if (count == 30) return false;
          return true;
        });
      }
      Log.d('Disposing ad');
      adUnit?.dispose();
      adUnit = null;
      _isLoaded = false;
    } catch (e) {
      Log.d('ad failed to dispose - $e');
    }
  }
}

我在两个地方调用 dispose 方法:

  1. 有状态小部件的 dispose 方法。
  2. 在导航到下一个屏幕之前。我无法在本地复制该问题,但我的许多用户向我发送了广告覆盖下一个屏幕的屏幕截图。

谢谢

4

0 回答 0