Flutter:使用共享首选项时对 null 的方法调用

Flutter : method call on null when using shared preference

我想使用共享首选项来保持用户登录,我正在使用 api 和提供者。 我试图将它放在主页面中,但我不知道该怎么做,因为我有两个不同的页面,所以我在第一页中使用了它,但我发现了另一个错误

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'login' was called on null. E/flutter ( 4199): Receiver: null

这是我使用的方法

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;
  }

所以任何人都有解决这个问题的想法!

正在对未初始化的变量进行方法调用 await userProvider.login(context, phone, pass);UserProvider userProvider; 已声明但未初始化

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

也是如此

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

要解决此问题,请执行以下操作, 在初始状态,

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