Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BannerAd.dispose Not Working Flutter Admob

I'm currently trying to display an admob banner in my app, However there are two pages where I would not like the banner displayed (For now i'm testing with just the settings route), And calling dispose on the banner does not hide it.

What I tried:

  1. Creating the banner for each widget and calling the dispose method inside the override of the widget's onDispose method
  2. Creating an Ad manager class that created the banner and saved a reference to it, and invoking a function from said class that calls dispose on the banner inside the init of the page I don't want the banner shown on.
  3. My current solution: an observer class that shows the banner on push, and if the name of the route matches what I'm looking for hides the banner.

So far none of these approaches have been successful :( What am I doing wrong? Am I missing something?

Observer class:

class AdmobObserver extends RouteObserver<PageRoute<dynamic>> {

  static ValueNotifier<bool> isBannerAdShowing = ValueNotifier<bool>(false);

  BannerAd _myBanner = BannerAd(
    adUnitId: AdManager.bannerAdUnitId,
    size: AdSize.banner,
    listener: (MobileAdEvent event) {
      if (event == MobileAdEvent.loaded) {
        isBannerAdShowing.value = true;
      }
      else if (event == MobileAdEvent.failedToLoad) {
        isBannerAdShowing.value = false;
      }
    },
  );

  @override
  void didPush(Route route, Route previousRoute) {
    super.didPush(route, previousRoute);
    if (route.settings.name == '/settings') {
      _myBanner?.dispose();
      isBannerAdShowing.value = false;
    } else {
      _showBannerAd();
    }
  }

  @override
  void didPop(Route route, Route previousRoute) {
    super.didPop(route, previousRoute);
    if (route.settings.name == '/settings') {
      _myBanner?.dispose();
      isBannerAdShowing.value = false;
    } else {
      _showBannerAd();
    }
  }

  void _showBannerAd() {
    _myBanner
      ..load()
      ..show();
  }
}

EDIT: I managed to get the observer to call dispose but now the banner either doesn't dispose or throws an exception: This exception occurs when I navigate from Home -> Settings -> Back to home (When the app is first built the banner disappears when I go to settings, but the error still occurs, but afterwards when I hot restart the same error occurs and the banner is still there, same error also happens when I pop into settings from a different page (Settings -> Page -> pop back to Settings)

 [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: 'package:firebase_admob/firebase_admob.dart': Failed assertion: line 249 pos 12: '_allAds[id] != null': is not true.
E/flutter (17108): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:42:39)
E/flutter (17108): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:38:5)
E/flutter (17108): #2      MobileAd.dispose (package:firebase_admob/firebase_admob.dart:249:12)
E/flutter (17108): #3      AdmobObserver.didPop (package:Switcheroo/AdManager.dart:87:18)
like image 303
barbecu Avatar asked Jun 23 '20 22:06

barbecu


2 Answers

You need to dispose the banner like this

try {
      _myBanner?.dispose();
      _myBanner = null;
    } catch (ex) {
      log("banner dispose error");
    }
like image 144
Koby 27 Avatar answered Nov 15 '22 11:11

Koby 27


See here too, and the solution with the listener property on BannerAd. I still seem to need the catch block for the irritating error. Although at least this way the banner hides correctly.

https://github.com/flutter/flutter/issues/21474

like image 32
user1978019 Avatar answered Nov 15 '22 10:11

user1978019