【问题标题】:Flutter : method call on null when using shared preferenceFlutter:使用共享首选项时对 null 的方法调用
【发布时间】:2021-03-30 15:42:53
【问题描述】:

我想使用共享偏好来保持用户登录,并且我正在使用带有 provider 的 api。 我试图把它放在 main 但我不知道怎么做,因为我有两个不同的页面要走,所以我在第一页使用它,但我发现另一个错误

[错误:flutter/lib/ui/ui_dart_state.cc(177)] 未处理的异常: NoSuchMethodError:在 null 上调用了方法“登录”。 E/颤振 ( 4199):接收者:空

这是我使用的方法

UserProvider userProvider;
  ServiceProvider serviceProvider;
  bool alive = true;
  bool isLoading = false;
  var page;

  @override
  initState() {
    init();
    super.initState();
  }

  init() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool language = prefs.getBool('language');
    bool type = prefs.getBool('type');
    bool login = prefs.getBool('islog');
    if (alive) {
      if (language == true && type == true && login == true) {
        signIn();
      } else if ((language == true && type == false && login == true)) {
        visitor();
      }
    } else {
      if (alive) {
        setState(() {
          isLoading = false;
        });
      }
    }
  }

  signIn() async {
    //var res = await userProvider.residentLogin(context, phone, pass);
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var phone = prefs.getString('phone');
    String pass = prefs.getString("pass");
    bool type = prefs.getBool('type');
      print("Shared ***************resident********************************");
      await userProvider.residentLogin(context, phone, pass);
      await serviceProvider.getHomeServiceList(context);
      await serviceProvider.getAdsList(context);
      await serviceProvider.getVideosList(context);
      Navigator.pushReplacement(context,
          MaterialPageRoute(builder: (context) => ResidentBottomTab()));
      print('Hello Tourist !!');
    
  }

  visitor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var phone = prefs.getString('phone');
    String pass = prefs.getString("pass");
    await userProvider.login(context, phone, pass);
    await serviceProvider.getVisitorAdsList(context);
    await serviceProvider.getVisitorVideosList(context);
    bool type = prefs.getBool('type');
    print("Shared ******************visitor*****************************");
    if (alive) {
      Navigator.pushReplacement(
          context, MaterialPageRoute(builder: (context) => VisitorHome()));
      print('Hello Tourist !!');
    }
  }

  @override
  void dispose() {
    alive = false;
    super.dispose();
  }

登录方式

Future<VisitorLoginModel> login(BuildContext context, phone, pass) async {
    final Map<String, dynamic> body = {
      'phone': phone,
      'password': pass,
      'token': '123',
      'serial_number': '123',
      'lang': 'en',
      'os': 'android',
    };

    _isLoading = true;
    notifyListeners();
    print('Starting request');
    http.Response response = await http.post(Environment.userLogin,
        body: json.encode(body), headers: Environment.requestHeader);
    print('Completed request');
    print('user SignUp response : ${response.body}');
    //print(body.toString());
    Map<String, dynamic> res = json.decode(response.body);
    var results;
    if (res['status'] == 1) {
      // login successful
      _visitorLoginModel = parseVisitorLogin(response.body);
      Provider.of<LoginVisitorUserProvider>(context, listen: false).userData =
          visitorLoginModel;
      Provider.of<LoginVisitorUserProvider>(context, listen: false)
          .sessionToken = visitorLoginModel.data.token;
      headers = Provider.of<LoginVisitorUserProvider>(context, listen: false)
          .httpHeader;
      // print('token');
      print('this is session token' +
          Provider.of<LoginVisitorUserProvider>(context, listen: false)
              .sessionToken);
    } else {
      // login failed;
      results =
          FailedRequest(code: 401, message: res['massage'], status: false);
    }
    _isLoading = false;
    notifyListeners();
    return visitorLoginModel;
  }

所以任何人都有解决此案的想法!

【问题讨论】:

    标签: api flutter dart sharedpreferences provider


    【解决方案1】:

    这里的问题是 userProvider 正在声明但未初始化,serviceProvider 也是如此

    在 Flutter 中,任何未初始化的变量都会隐式赋值为 null 因此,在 await userProvider.login(context, phone, pass); 行,您调用 login 方法,其中 userProvider 不仅被初始化

    要解决此问题,请执行以下操作, 在 initState 中,

    userProvider = Provider.of<UserProvider>(context, listen: false);
    

    【讨论】:

      【解决方案2】:

      方法调用await userProvider.login(context, phone, pass); 正在一个未初始化的变量上完成。 UserProvider userProvider; 已声明但未初始化

      【讨论】:

      • 这是对的,请您提一下如何在 main 中使用它?
      • @MariamYounes 请参考我现在附上的答案。您必须在 initState 中对其进行初始化
      • 我有问题,请检查一下
      • 但仍然不知道如何在 main 上使用共享偏好方法
      猜你喜欢
      • 1970-01-01
      • 2019-10-01
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 2023-03-23
      • 2018-10-02
      • 2015-11-29
      • 1970-01-01
      相关资源
      最近更新 更多