我有检查flutter应用程序版本的代码,但它包含一个asynchron代码,我不能在buildcontext方法中插入,所以我决定将其放入main方法并插入一个弹出窗口,告诉用户他必须更新应用程序,但我收到了这个回复:失败的断言:第70行pos 15:上下文!=null: is not true因为我在alertDialog中将context设置为null,所以id不知道将其放置在哪里,以便每次用户启动应用程序时,版本检查都在运行,如果他拥有的版本小于商店中的版本,则会显示alertDialog。这是我检查它的代码以及我如何实现它:我使用NewVersion包来检查和比较本地版本和谷歌播放中存储的版本
class PataStoreConnector extends StatefulWidget {
final bool loggedin;
PataStoreConnector({Key key, this.loggedin}) : super(key: key);
@override
_PataStoreConnectorState createState() => _PataStoreConnectorState();
}
class _PataStoreConnectorState extends State<PataStoreConnector> {
bool sleeping = true;
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
timer();
});
super.initState();
}
@override
Widget build(BuildContext context) {
if (sleeping) {
return PataSplashScreen();
}
return StoreConnector<PataState, PataViewModel>(
converter: PataViewModel.convertStateToViewModel,
builder: (BuildContext context, PataViewModel pataViewModel) {
return getPage(pataViewModel);
},
);
}
以及包含检查版本代码的getPage方法:
// ignore: missing_return
Widget getPage(PataViewModel viewModel) {
//Pt.instance.version;
final newVersion = NewVersion(
androidId: 'com.snedac.empata',
context: context,
);
// setState(() async {
// VersionStatus vs = await newVersion.getVersionStatus();
// });
newVersion.getVersionStatus().then((result) {
print("store version ${result.storeVersion}");
print("local version ${result.localVersion}");
if (result.storeVersion == result.localVersion) {
if (viewModel.isLoggingIn()) {
viewModel.refreshUserData();
// vm.setIsHomeLoadedStateAction(true);
return PataSplashScreen();
}
if (!viewModel.isLoggedIn()) {
return LoginPage(
viewModel: viewModel,
);
}
print("homeloaded:${viewModel.state.isHomeloaded}");
print("userIdLogin:${viewModel.state.user.userId}");
if (viewModel.state.isHomeloaded == false) {
if (viewModel.state.user.userId > 0) {
viewModel.initHome();
} else {
return LoginPage(
viewModel: viewModel,
);
}
}
return PataHome(title: "e-Mpata");
} else {
_ackAlert2("Mise a jour", 'Votre version est trop obsolète.');
}
});
}
您永远不需要在build()
方法中执行async
工作。如果您想在启动时显示过期版本的错误,您可以执行以下代码:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); // make sure plugins are initialized properly
final isOutOfDate = await checkAppOutOfDate(); // do the check
runApp(MyApp(isOutOfDate: isOutOfDate)); // pass the boolean to your app as a parameter
}
然后,您可以修改MyApp()
(或任何位于小部件树根目录的东西)以接受此参数并正确处理它:
class MyApp extends StatefulWidget {
final bool isOutOfDate;
MyApp({required this.isOutOfDate});
@override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
// a bit like initState(), but has access to a live BuildContext
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (widget.isOutOfDate) {
showDialog(context, ...); // show a dialog to the user with a proper BuildContext
}
}
@override
Widget build(BuildContext context) {
...
}
}
如果您希望在initState
中显示对话框,则必须延迟显示它,例如:
@override
void initState() {
super.initState();
SchedulerBinding.instance!.addPostFrameCallback((_) => showDialog(context, ...));
}
但在这种情况下两者都会达到相似的结果