提问者:小点点

如何在应用程序上检查版本?


我有检查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.');
  }
});

}


共1个答案

匿名用户

您永远不需要在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, ...));
}

但在这种情况下两者都会达到相似的结果