Skip to content

[Android] Severe glitch when navigating to a screen with google_mobile_ads  #95343

@peterwvj

Description

@peterwvj

Upgrading to Flutter 2.8.0 causes flickering when navigating between screens in apps that contain ads. In particular, the flickering happens when navigating to a new screen from another screen that has a banner ad. When commenting out the banner the flickering goes away.

The problem is not producible using Flutter 2.5.3.

The issue was originally raised in googleads-mobile-flutter but after investigating the issue further it is now believed to be a problem with the Flutter SDK.

To produce the problem, run the attached application code using google_mobile_ads: 1.0.1 and Flutter 2.8.0.

Video sample, code sample and flutter doctor -v output produced by @maheshmnj

Code sample
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: HomeScreen());
  }
}



class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(child: ListView.builder(itemBuilder: (context, index) {
            return ListTile(
              title: Text('Item $index'),
              onTap: () {
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return const ProducDetailPage();
                }));
              },
            );
          })),
          const CustomBannerAd()
        ],
      ),
    );
  }
}

class ProducDetailPage extends StatelessWidget {
  const ProducDetailPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Produc Detail'),
        ),
        body: Column(children: const [
          SizedBox(
            height: 150,
            child: Placeholder(
              color: Colors.red,
            ),
          ),
          SizedBox(
            height: 150,
            child: Placeholder(
              color: Colors.green,
            ),
          ),
          CustomBannerAd()
        ]));
  }
}

class CustomBannerAd extends StatefulWidget {
  const CustomBannerAd({Key? key}) : super(key: key);

  @override
  _CustomBannerAdState createState() => _CustomBannerAdState();
}

class _CustomBannerAdState extends State<CustomBannerAd> {
  BannerAd? _anchoredAdaptiveAd;
  var _isLoaded = false;
  late Orientation _currentOrientation;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    _currentOrientation = MediaQuery.of(context).orientation;
    _loadAd();
  }

  @override
  void dispose() {
    super.dispose();

    _anchoredAdaptiveAd?.dispose();
  }

  Future<void> _loadAd() async {
    await _anchoredAdaptiveAd?.dispose();

    if (mounted) {
      setState(() {
        _anchoredAdaptiveAd = null;
        _isLoaded = false;
      });
    }

    final AnchoredAdaptiveBannerAdSize? size =
        await AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
            MediaQuery.of(context).size.width.truncate());

    if (size == null) {
      debugPrint('Unable to get height of anchored banner.');
      return;
    }

    _anchoredAdaptiveAd = BannerAd(
      adUnitId: Platform.isAndroid
          ? 'ca-app-pub-3940256099942544/6300978111'
          : 'ca-app-pub-3940256099942544/2934735716',
      size: size,
      request: const AdRequest(
        nonPersonalizedAds: false,
      ),
      listener: BannerAdListener(
        onAdLoaded: (Ad ad) {
          debugPrint("Ad loaded");
          if (mounted) {
            setState(() {
              _anchoredAdaptiveAd = ad as BannerAd;
              _isLoaded = true;
            });
          }
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          debugPrint('$BannerAd failedToLoad: $error');
          ad.dispose();
        },
        onAdOpened: (Ad ad) => debugPrint('$BannerAd onAdOpened.'),
        onAdClosed: (Ad ad) => debugPrint('$BannerAd onAdClosed.'),
      ),
    );

    return _anchoredAdaptiveAd?.load();
  }

  @override
  Widget build(BuildContext context) {
    return OrientationBuilder(builder: (context, orientation) {
      if (_currentOrientation == orientation &&
          _anchoredAdaptiveAd != null &&
          _isLoaded) {
        return Container(
          color: Colors.transparent,
          width: _anchoredAdaptiveAd!.size.width.toDouble(),
          height: _anchoredAdaptiveAd?.size.height.toDouble(),
          child: AdWidget(ad: _anchoredAdaptiveAd!),
        );
      }

      // Reload the ad if the orientation changes.
      if (_currentOrientation != orientation) {
        _currentOrientation = orientation;
        _loadAd();
      }
      return const SizedBox.shrink();
    });
  }
}

Video showing the bug (Flutter 2.8.0), This bug is not reproducible using Flutter 2.5.3:

stable 2.8.0 stable 2.5.3
flutter-2.8.0-bug.mov
flutter-2.5.3-no-bug.mov

Can presumably be reproduced using any Android 12 device. See flutter doctor -v output for details.

flutter doctor -v
[✓] Flutter (Channel stable, 2.8.0, on macOS 12.0.1 21A559 darwin-arm, locale en-GB)
    • Flutter version 2.8.0 at /Users/mahesh/Documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision cf44000065 (2 days ago), 2021-12-08 14:06:50 -0800
    • Engine revision 40a99c5951
    • Dart version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/mahesh/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.10.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] IntelliJ IDEA Community Edition (version 2021.2.1)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 60.1.4
    • Dart plugin version 212.5080.8

[✓] VS Code (version 1.61.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.29.0

[✓] Connected device (3 available)
    • Redmi K20 Pro (mobile) • 192.168.1.6:5555 • android-arm64  • Android 11 (API 30)
    • macOS (desktop)        • macos            • darwin-arm64   • macOS 12.0.1 21A559 darwin-arm
    • Chrome (web)           • chrome           • web-javascript • Google Chrome 96.0.4664.93

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: performanceRelates to speed or footprint issues (see "perf:" labels)c: regressionIt was better in the past than it is nowcustomer: crowdAffects or could affect many people, though not necessarily a specific customer.engineflutter/engine related. See also e: labels.f: routesNavigator, Router, and related APIs.found in release: 2.8Found to occur in 2.8found in release: 2.9Found to occur in 2.9has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions