Flutter:使用共享首选项时对 null 的方法调用
Posted
技术标签:
【中文标题】Flutter:使用共享首选项时对 null 的方法调用【英文标题】:Flutter : method call on null when using shared preference 【发布时间】: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;
所以任何人都有解决此案的想法!
【问题讨论】:
【参考方案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 上使用共享偏好方法以上是关于Flutter:使用共享首选项时对 null 的方法调用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 dart/flutter 中的共享首选项保存和获取列表列表
Flutter 中的共享首选项错误 - Mac 上的 iOS