首页 > 解决方案 > 如何使用 Flutter Google Mobile Ads with provier (MVVM)

问题描述

我可以使用下面的代码展示广告。但是我认为这段代码很难编写测试代码。这就是为什么我要创建 ViewModel 文件并传输逻辑来查看模型的原因。

可以使用此代码显示广告

class BannerAdWidget extends StatefulWidget {
  BannerAdWidget({@required this.size});

  final AdSize size;

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

class _BannerAdWidgetState extends State<BannerAdWidget> {
  BannerAd _bannerAd;
  bool _isReady = false;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(seconds: 1), createAd);
  }

  createAd() {
    _bannerAd = BannerAd(
      size: widget.size,
      adUnitId: BannerAd.testAdUnitId,
      request: AdRequest(),
      listener: AdListener(
        onAdLoaded: (ad) {
          print('${ad.runtimeType} loaded!');
          setState(() {
            _isReady = true;
          });
        },
        onAdFailedToLoad: (ad, error) {
          print('${ad.runtimeType} failed to load.\n$error');
          ad.dispose();
          _bannerAd = null;
        },
        onApplicationExit: (Ad ad) =>
            print('${ad.runtimeType} onApplicationExit.'),
      ),
    )..load();
  }

  @override
  void dispose() {
    _bannerAd?.dispose();
    _bannerAd = null;
    super.dispose();
  }

  @override
  void didUpdateWidget(covariant BannerAdWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    _bannerAd?.dispose();
    _bannerAd = null;
    createAd();
    setState(() {
      _isReady = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange,
      width: widget.size.width.toDouble(),
      height: widget.size.height.toDouble(),
      child: _isReady
          ? AdWidget(ad: _bannerAd)
          : Center(
              child: CircularProgressIndicator(),
            ),
    );
  }
}

我尝试创建 ViewModel 文件并将 logix 传输到 viewModel。

我试图将逻辑转换为代码的代码

banner_ad_widget.dart

import 'package:feed_n/parts/molecules/advertising/banner_ad_widget_view_model.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:provider/provider.dart';

class BannerAdWidget extends StatefulWidget {
  BannerAdWidget({@required this.size});

  final AdSize size;

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

class _BannerAdWidgetState extends State<BannerAdWidget> {
  BannerAdWidgetViewModel _bannerAdWidgetViewModel;

  @override
  void initState() {
    super.initState();
    _bannerAdWidgetViewModel = Provider.of<BannerAdWidgetViewModel>(context, listen: false);
    Future.delayed(
      const Duration(seconds: 1),
      _bannerAdWidgetViewModel.createAd(widget.size)
    );
  }


  @override
  void dispose() {
    _bannerAdWidgetViewModel.disposeAd();
    super.dispose();
  }

  @override
  void didUpdateWidget(covariant BannerAdWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    _bannerAdWidgetViewModel.disposeAd();
    _bannerAdWidgetViewModel.createAd(widget.size);
    _bannerAdWidgetViewModel.isReady = false;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      width: widget.size.width.toDouble(),
      height: widget.size.height.toDouble(),
      child: _bannerAdWidgetViewModel.isReady
          ? AdWidget(ad: _bannerAdWidgetViewModel.bannerAd)
          : Container()
    );
  }
}

banner_ad_widget_view_model.dart

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

class BannerAdWidgetViewModel extends ChangeNotifier {
  BannerAd bannerAd;
  bool isReady = false;

  // ignore: always_declare_return_types
  createAd(AdSize size) {
    bannerAd = BannerAd(
      size: size,
      adUnitId: BannerAd.testAdUnitId,
      request: const AdRequest(),
      listener: AdListener(
        onAdLoaded: (ad) {
          isReady = true;
        },
        onAdFailedToLoad: (ad, error) {
          ad.dispose();
          bannerAd = null;
        },
        onApplicationExit: (Ad ad) {

        }
      ),
    )..load();
    print("aaa");
    notifyListeners();
  }

  void disposeAd() {
    bannerAd.dispose();
    bannerAd = null;
    notifyListeners();
  }
}

不起作用的东西

此代码不起作用,应用程序被强制终止。

      #51 pc 007a11b7  /apex/com.android.art/lib/libart.so (MterpInvokeVirtual+967) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #52 pc 001357a1  /apex/com.android.art/lib/libart.so (mterp_op_invoke_virtual+33) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #53 pc 0044928e  /system/framework/framework.jar (offset 0x125d000) (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run+22)
      #54 pc 0036fb02  /apex/com.android.art/lib/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16375758241455872412)+370) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #55 pc 00379b00  /apex/com.android.art/lib/libart.so (art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*)+176) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #56 pc 0078b325  /apex/com.android.art/lib/libart.so (artQuickToInterpreterBridge+1061) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #57 pc 0014220d  /apex/com.android.art/lib/libart.so (art_quick_to_interpreter_bridge+77) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #58 pc 00893656  /system/framework/x86/boot-framework.oat (com.android.internal.os.ZygoteInit.main+2102) (BuildId: 9a9778e61b43d349325d0bb85244bd9bc95ff387)
      #59 pc 0013baf2  /apex/com.android.art/lib/libart.so (art_quick_invoke_static_stub+418) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #60 pc 001d0392  /apex/com.android.art/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+258) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #61 pc 0062e653  /apex/com.android.art/lib/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, char*)+579) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #62 pc 0062eb25  /apex/com.android.art/lib/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, char*)+85) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #63 pc 004ce64f  /apex/com.android.art/lib/libart.so (art::JNI<true>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+735) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #64 pc 003f8aae  /apex/com.android.art/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, char*, art::Primitive::Type, art::InvokeType)+2846) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #65 pc 003e60d9  /apex/com.android.art/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+73) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
      #66 pc 0008f90e  /system/lib/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+62) (BuildId: 588f2cd5873ff4273bb25b25edb82606)
      #67 pc 00098c8e  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+910) (BuildId: 588f2cd5873ff4273bb25b25edb82606)
      #68 pc 00003804  /system/bin/app_process32 (main+1588) (BuildId: c5eedbfb6130af84c3db8e121fb1202e)
      #69 pc 000522e3  /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+115) (BuildId: 6e3a0180fa6637b68c0d181c343e6806)
Lost connection to device.
Exited (sigterm)

如果我想展示广告,如何编写 viewModel 代码?

标签: flutterdartprovider

解决方案


推荐阅读