Async initialization of services during startup

https://bsky.app/profile/sander-roest.bsky.social
Search for a command to run...

https://bsky.app/profile/sander-roest.bsky.social
No comments yet. Be the first to comment.
In this series I will tell my adventures with Flutter and Line Of Business Apps
The importance and usage of logging is for Line Of Business apps different than for consumer apps. Consumer apps Collect application crashes/warnings Narrow down problems to specific manufacturers, hardware, os versions Get insights on how much the ...
Running flutter upgrade is not enough...

A necessity or a rip-off?

Both are used by humans, but they are not the same.

Recap part 1. In the previous article about this subject, I explained the limitations that I have ran into, with the default onDidRemovePage implementation. In this article I will show how I’ve overcome or better said, circumvented these limitations....
During the development of my RubigoRouter package I ran into some limitations of the Navigator object that I explain here below. The Flutter Navigator has a mechanism to inform the app about a back navigation event. Historically the onPopPage callbac...
Startup phases:
The first thing that happens when a Flutter app starts, is the bootstrapping of the native platform code. This piece is responsible for showing the splash screen and creating a container where the Flutter app can live. As soon as everything is ready, the main function in the /lib folder is executed. This main function is responsible for bootstrapping the Flutter code.
The bootstrapping of the Flutter code is where things might get complicated due to the async nature of Flutter and the usage of Provider to provide services and state. The reason for this is:
To complicate things even further, some services are dependant on other services and the order of initialization of the services might matter.
One might try to initialize all the services before runApp(MyApp()) is called.
Future<void> main() async {
await initAllServicesAndState();
runApp(MyApp());
}
This has some major downsides:
Another approach is to initially build a user interface that is not dependant on any services or state. The only responsibility of this page is to initialize things. In my project, this is called AppStartPage.
I decided to take the following approach:
class AppStartPage extends StatefulWidget {
@override
\_AppStartPageState createState() => \_AppStartPageState();
}
class \_AppStartPageState extends State<AppStartPage> {
@override
void initState() {
super.initState();
onStart();
}
Future<void> onStart() async {
await Provider.of<VersionService>(context, listen: false).init();
await Provider.of<SoundService>(context, listen: false).init();
await Provider.of<ConfigurationBoxService>(context, listen: false).init();
await Provider.of<ConfigurationLoader>(context, listen: false).init();
await Provider.of<LoggingServiceFile>(context, listen: false).init();
Provider.of<LoggingServiceFile>(context, listen: false).connectLogWriter();
await Provider.of<DatawedgeService>(context, listen: false).init();
await Navigator.pushReplacement(context, HomePage.Route);
}
@override
Widget build(BuildContext context) {
return Container();
}
}
In this sample, the AppStartPage is an empty container. In a real app, you might want to show a page that informs the user what is going on, like ‘Loading….’.
A downside is that the app now has two splash screens. The first is coming from the Android/iOS project. The second one is AppStartPage.
But the advantages of an AppStartPage are obvious: