FutureBuilder не ждет завершения будущего

В моем приложении я хочу что-то инициализировать до того, как будут созданы мои виджеты. Мне нужно сделать это ровно в Appclass и пытается использовать FutureBuilder для этой цели. Но _AppBlocProviderс build метод вызывается до initInjectionContainer(), Например. Мой репозиторий еще не инициализирован в инъекционном контейнере, но блоки в поставщике пытаются получить доступ к его экземпляру. Что не так с этим кодом?

Я тоже пробовал это:

      void main() {
  runApp(App());
}

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  Future<bool>? _myFuture;

  Future<bool> _init() async {
    ...
    await initInjectionContainer();
    await sl<AudioManager>().preloadFiles();
    return false;
  }

  ...

  @override
  void initState() {
    super.initState();
    _myFuture = _init();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _myFuture,
      builder: (context, _) {
        return _BlocProvider(
          child: Builder(
            builder: (context) => MaterialApp(
              title: 'Flutter Demo',
              theme: ThemeData(
                primarySwatch: Colors.blue,
              ),
              home: MainMenu(),
            ),
          ),
        );
      },
    );
  }
}

не работает.

1 ответ

Решение

не просто автоматически блокирует или показывает экран загрузки или что-то еще. Он строится один раз при инициализации, а затем еще раз, когда завершится будущее. Этот второй параметр в построителе, который вы анонимизировали, имеет решающее значение для правильного управления состоянием будущего и соответствующего строительства.

      FutureBuilder(
  future: _someFuture(),
  builder: (context, snapshot) {
    if (snapshot.connectionState != ConnectionState.done) {
      // Future not done, return a temporary loading widget
      return CircularProgressIndicator();
    }

    // Future is done, handle it properly
    return ...
  },
),

При этом, если есть что-то, что нужно всему вашему приложению, которое вам нужно инициализировать, вы можете вызвать его из прежде чем позвонить так что они становятся частью процесса загрузки среды выполнения, а не заставляют виджет иметь дело с этим:

      void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await initInjectionContainer();
  await sl<AudioManager>().preloadFiles();

  runApp(App());
} 

Теперь , что , как говорится, если эти процессы могут занять некоторое время, то лучше обработать их с помощью виджета , так что вы можете отобразить состояние загрузки пользователю , чтобы они знали приложение не просто замерзать на старт-ап.

Другие вопросы по тегам