【问题标题】:The method was called on null该方法在 null 上调用
【发布时间】:2018-10-20 18:17:26
【问题描述】:

我正在尝试使用 firebase 分析来跟踪用户导航并按下一些按钮,我创建了一个 _currentScreen() 函数,我在用户导航到的类中调用了 init state 这是函数

Future<Null> _currentScreen() async {
    await widget.analytics.setCurrentScreen(
        screenName: 'second screen view', screenClassOverride: 'SecondScreenView');
  }

我创建了另一个函数,即 _sendAnalytics,当用户单击按钮时我会调用它;这是函数:

 Future<Null> _sendAnalytics() async {
    await widget.analytics
        .logEvent(name: 'launchhhh', parameters: <String, dynamic>{});

  }

我有几个问题: 第一个 - 在第二个屏幕类的 initstate 中,它发出警告:is 方法覆盖了一个在“State”中注释为 @mustCallSuper 的方法,但不调用被覆盖的方法。 第二-当我运行代码并按下导航按钮时,我有这个

[ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
E/flutter (12744): NoSuchMethodError: The method 'logEvent' was called on null.
E/flutter (12744): Receiver: null
E/flutter (12744): Tried calling: logEvent(name: "launchhhh", parameters: _LinkedHashMap len:0)
E/flutter (12744): #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
E/flutter (12744): #1      FirstScreenState._sendAnalytics (file:///C:/Users/pc/Desktop/wedn2/wedn2/lib/h.dart:40:10)

3- 另外,当我评论 _sendanalytics 函数时

NoSuchMethodError: The method 'setCurrentScreen' was called on null.
E/flutter (15612): Receiver: null
E/flutter (15612): Tried calling: setCurrentScreen(screenClassOverride: "SecondScreenView", screenName: "second screen view")
E/flutter (15612): #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
E/flutter (15612): #1      SecondScreenState._currentScreen (file:///C:/Users/pc/Desktop/wedn2/wedn2/lib/h.dart:91:28)
E/flutter (15612): <asynchronous suspension>
E/flutter (15612): #2      SecondScreenState.initState (file:///C:/Users/pc/Desktop/wedn2/wedn2/lib/h.dart:88:5)
E/flutter (15612): #3      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3787:58)
E/flutter (15612): #4      ComponentElement.mount (package:flutter/src/widgets/framework.dart:3653:5)

不知道哪里有问题?这是我的全部代码:

import 'package:flutter/material.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';

import 'dart:async';


 class MyAppf extends StatelessWidget {
  static FirebaseAnalytics analytics = new FirebaseAnalytics();
  static FirebaseAnalyticsObserver observer =
      new FirebaseAnalyticsObserver(analytics: analytics);


  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      navigatorObservers: <NavigatorObserver>[observer],
      // home: new WallScreen(analytics: analytics, observer: observer),
      home: new FirstScreen(),
    );
  }
}
class FirstScreen extends StatefulWidget {
  final FirebaseAnalytics analytics;
  final FirebaseAnalyticsObserver observer;
  FirstScreen({this.analytics, this.observer});


  @override
  FirstScreenState createState() => new FirstScreenState();
}
class FirstScreenState extends State<FirstScreen> {
  Future<Null> _sendAnalytics() async {
    await widget.analytics
        .logEvent(name: 'launchhhh', parameters: <String, dynamic>{});

  }

    final FirebaseAnalytics analytics;
  final FirebaseAnalyticsObserver observer;
  FirstScreenState({this.analytics, this.observer});

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      appBar: AppBar(
        title: Text('First Screen'),
      ),


      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondScreen()),
            );
           _sendAnalytics();
          },
        ),
      ),
    );
  }
}
class SecondScreen extends StatefulWidget {


  final FirebaseAnalytics analytics;
  final FirebaseAnalyticsObserver observer;
  SecondScreen({this.analytics, this.observer});



  @override
  SecondScreenState createState() => new SecondScreenState();
}

class SecondScreenState extends State<SecondScreen> {
  @override
  void initState() {
    _currentScreen();
  }
   Future<Null> _currentScreen() async {
    await widget.analytics.setCurrentScreen(
        screenName: 'second screen view', screenClassOverride: 'SecondScreenView');
  }
  Future<Null> _sendAnalyticsback() async {
    await widget.analytics
        .logEvent(name: 'back', parameters: <String, dynamic>{});

  }
  final FirebaseAnalytics analytics;
  final FirebaseAnalyticsObserver observer;
  SecondScreenState({this.analytics, this.observer});  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          _sendAnalyticsback();
          },
          child: Text('Go back!'),
        ),
      ),
    );


  }

}

编辑我将我的 var 分析传递给 Widgets 以成为

 home:new FirstScreen(analytics: analytics),
Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondScreen(analytics:analytics)),

而不是:

home:new FirstScreen(),
Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondScreen()),

但调用 null 仍然是同样的错误

【问题讨论】:

    标签: firebase navigation flutter analytics init


    【解决方案1】:

    您需要将 var 分析传递给小部件。

    new FirstScreen(),
    new SecondScreen(),
    

    应该是:

    new FirstScreen(analytics: analytics),
    new SecondScreen(analytics: analytics),
    

    【讨论】:

    • 感谢您的回复;我这样做了,但仍然没有工作
    【解决方案2】:

    不要使用静态成员,因为它们旨在通过类本身访问。您尝试做的一种更简单的方法是将 MyApp 声明为 SatetfulWidget ,现在您 analyticsobserver 可以是 State 类的私有成员并使用 initState 来初始化它们,请参阅下面的例子:

    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
       FirebaseAnalytics _analytics;
       FirebaseAnalyticsObserver _observer ;
      @override
        void initState() {
          _analytics = FirebaseAnalytics();
          _observer = FirebaseAnalyticsObserver(analytics: _analytics);
          super.initState();
        }
    
      @override
      Widget build(BuildContext context) {
        return  Container();
      }
    }
    

    如果您想保留您的小部件Stateless,您可以在构造函数的初始化列表中初始化您的observer,这需要在创建MyApp 时向analytics 字段传递一个值MyApp(analytics:FirebaseAnalytics())

    class MyApp extends StatelessWidget {
      final FirebaseAnalytics analytics;
      final FirebaseAnalyticsObserver observer;
    
      MyApp({Key key,@required this.analytics})
          : observer = FirebaseAnalyticsObserver(analytics: analytics),
            super(key: key);
    
    
    
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-02
      • 2019-12-26
      • 2021-04-27
      • 2020-01-17
      • 2020-02-21
      • 2021-02-26
      • 2021-08-22
      • 2020-12-03
      相关资源
      最近更新 更多