Provider 在应用程序启动时使用 SharedPreferences
Using SharedPreferences by Provider on application startup
我有 2 个启动页面,如果我在共享首选项中的“登录”下没有任何值,我想要 运行 PgStartupNew。但是我不能这样做,因为 SharedPreferences 还没有初始化。我怎样才能解决这个问题?
main.dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
// Provider<Future>(create: (_) => Future.value(42)),
Provider<MySharedPreferences>(
create: (_) => MySharedPreferences.create()),
Provider<User>(create: (_) => User.create()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: MyStyle.getThemeData(),
title: 'TestApp',
home: PgSelectStartup(),
),
);
}
}
class PgSelectStartup extends StatelessWidget {
@override
Widget build(BuildContext context) {
return (Provider.of<MySharedPreferences>(context).read("login") ==
null)
? PgStartupNew()
: PgStartupLogin();
}
}
my_shared_preferences.dart
String? read(String key) {
return prefs.getString(key) ?? null;
}
错误:
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building PgSelectStartup(dirty, dependencies: [_InheritedProviderScope<MySharedPreferences>]):
The method 'getString' was called on null.
Receiver: null
Tried calling: getString("login")
我尝试在构建 return 之前添加一个额外的调用 read() 方法,并尝试强制重新初始化 SharedPrefs,但它仍然无法正常工作。 class PgSelectStartup 中对 read() 的每次第一次调用都失败了,因为 prefs == null。
我该如何解决?当prefs已经初始化时如何使用“Widget build(BuildContext context)”?
我发现了一些情况如何做到这一点,但 none 在我的情况下工作,我在启动时使用 SharedPrefs,而且通过 MultiProvider
使用它
如果您想在启动时访问共享首选项,您需要在 main
中调用 runApp
之前对其进行初始化:
await MySharedPreferences.create();
// Initialize all needed asynchronous singletons.
runApp(MyApp());
最后我使用 FutureBuilder 修复了它,新代码:
class PgSelectStartup extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Provider.of<MySharedPreferences>(context).myNewInitSync(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return (Provider.of<MySharedPreferences>(context)
.read("login") ==
null)
? PgStartupNew()
: PgStartupLogin();
} else {
return Column(
children: [
CircularProgressIndicator(),
],
);
}
},
);
}
}
MySharedPreferences 中的新方法:
//old:
static void myNewInit() async {
prefs = await SharedPreferences.getInstance();
}
// new:
Future<SharedPreferences> myNewInitSync() {
return prefs = SharedPreferences.getInstance();
}
我有 2 个启动页面,如果我在共享首选项中的“登录”下没有任何值,我想要 运行 PgStartupNew。但是我不能这样做,因为 SharedPreferences 还没有初始化。我怎样才能解决这个问题?
main.dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
// Provider<Future>(create: (_) => Future.value(42)),
Provider<MySharedPreferences>(
create: (_) => MySharedPreferences.create()),
Provider<User>(create: (_) => User.create()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: MyStyle.getThemeData(),
title: 'TestApp',
home: PgSelectStartup(),
),
);
}
}
class PgSelectStartup extends StatelessWidget {
@override
Widget build(BuildContext context) {
return (Provider.of<MySharedPreferences>(context).read("login") ==
null)
? PgStartupNew()
: PgStartupLogin();
}
}
my_shared_preferences.dart
String? read(String key) {
return prefs.getString(key) ?? null;
}
错误:
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building PgSelectStartup(dirty, dependencies: [_InheritedProviderScope<MySharedPreferences>]):
The method 'getString' was called on null.
Receiver: null
Tried calling: getString("login")
我尝试在构建 return 之前添加一个额外的调用 read() 方法,并尝试强制重新初始化 SharedPrefs,但它仍然无法正常工作。 class PgSelectStartup 中对 read() 的每次第一次调用都失败了,因为 prefs == null。 我该如何解决?当prefs已经初始化时如何使用“Widget build(BuildContext context)”? 我发现了一些情况如何做到这一点,但 none 在我的情况下工作,我在启动时使用 SharedPrefs,而且通过 MultiProvider
使用它如果您想在启动时访问共享首选项,您需要在 main
中调用 runApp
之前对其进行初始化:
await MySharedPreferences.create();
// Initialize all needed asynchronous singletons.
runApp(MyApp());
最后我使用 FutureBuilder 修复了它,新代码:
class PgSelectStartup extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Provider.of<MySharedPreferences>(context).myNewInitSync(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return (Provider.of<MySharedPreferences>(context)
.read("login") ==
null)
? PgStartupNew()
: PgStartupLogin();
} else {
return Column(
children: [
CircularProgressIndicator(),
],
);
}
},
);
}
}
MySharedPreferences 中的新方法:
//old:
static void myNewInit() async {
prefs = await SharedPreferences.getInstance();
}
// new:
Future<SharedPreferences> myNewInitSync() {
return prefs = SharedPreferences.getInstance();
}