In my app I want to initialize something before my widgets will be created. I need to do it exactly in App
class and trying to use FutureBuilder for this purpose. But _AppBlocProvider
's build
method is called before initInjectionContainer()
, for example. My repository is not initialised yet in injectionContainer, but Blocs in provider are trying to access it's instance. What's wrong with this code?
I've also tried this:
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(),
),
),
);
},
);
}
}
doesn't work.
FutureBuilder
doesn't just automatically block or show a loading screen or whatever. It builds once on initialization, and then again once the future completes. That second parameter in the builder that you anonymized is crucial to properly handling the state of the future and building accordingly.That being said, if there is stuff that your entire app needs that you need to initialize, you can call it from
main
before you callrunApp
so that they become a part of the runtime loading process rather than forcing a widget to deal with it:Now with that being said, if these processes can take a while, it's better to handle them with a widget so that you can display a loading state to the user so they know the app didn't just freeze on start-up.