I would like to perform next using Xamarin:
when application starts splashScreen is immediately shown (I've achieved this following next tutorial https://channel9.msdn.com/Blogs/MVP-Windows-Dev/Using-Splash-Screen-with-Xamarin-Forms)
execute db migrations if any (in case user updated app and runs it the first time)
read user data (username and password) from db, call a REST webservice to check if user data are still valid. If user data is valid redirect user to MainPage otherwise redirect to LoginPage
I've read next good post about Xamarin.Forms Async Task On Startup. Current code:
public class MainActivity :global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
LoadApplication (new App ()); // method is new in 1.3
}
}
// shared code - PCL lib for Android and iOS
public partial class App : Application
{
public App()
{
InitializeComponent();
// MainPage = new LoadingPage();
}
}
protected override async void OnStart()
{
// Handle when your app starts
await App.Database.Migrations();
if( await CheckUser()) // reads user data from db and makes http request
this.MainPage = new Layout.BrowsePage();
else
this.MainPage = new LoginPage();
}
If MainPage
is not set in constructor Exception is thrown on iOS and Android. I know that async void doesn't wait if it does'not explicitly have .Wait()
-
Async void, but does this mean that executing thread still continues it's work.
When executing thread hits await App.Database.Migrations();
it pauses the execution and await for await Task to complete. Meanwhile it continues it's work (i.e. LoadApplication() continues to execute and expects that App.MainPage is set by now). Is my assumption correct?
I just want to avoid LoadingPage
because three screens are shown:
- splash screen (right when app is started)
- LoadingPage (db migrations, http request, ..)
- BrowsePage or LoginPage
Desirable would be just two pages, for user experience.
I ended up like this, but I believe there is a better approach:
protected override void OnStart()
{
Page startPage = null;
Task.Run(async() =>
{
await App.Database.Migrations();
startPage = await CheckUser() ? new Layout.BrowsePage() : new LoginPage();
}.Wait();
this.MainPage = startPage();
}