我想接下来使用Xamarin执行:
当应用程序启动时会立即显示splashScreen(我已经在下一个教程https://channel9.msdn.com/Blogs/MVP-Windows-Dev/Using-Splash-Screen-with-Xamarin-Forms之后实现了这一点)
执行db迁移(如果有)(如果用户更新了应用并且第一次运行它)
从db读取用户数据(用户名和密码),调用REST Web服务以检查用户数据是否仍然有效。如果用户数据有效,则将用户重定向到MainPage,否则重定向到LoginPage
我读过关于Xamarin.Forms Async Task On Startup的下一篇好文章。目前的代码:
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();
}
如果未在构造函数中设置MainPage
,则会在iOS和Android上抛出异常。我知道async void不会等待,如果它没有显式.Wait()
-
Async void,但这是否意味着执行线程仍然继续它的工作。
执行线程命中await App.Database.Migrations();
时,它会暂停执行并等待等待任务完成。同时它继续它的工作(即LoadApplication()继续执行并期望现在设置App.MainPage)。我的假设是否正确?
我只想避免LoadingPage
因为显示了三个屏幕:
对于用户体验,可取的只有两页。
我这样结束了,但我相信还有更好的方法:
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();
}
答案 0 :(得分:1)
那么你可以把所有内容都放到App构造函数中,并且当你加载应用程序时,启动画面只显示更长时间,但我实际上相信这是一个较差的解决方案。
有一个Splashscreen,然后是一个加载页面,它看起来与启动画面完全一样,但有一个进度条或加载图标,告诉用户它正在做什么,这是一个更好的方法。
如果你必须在用户看到第一页之前这样做,那么加载屏幕是一个很好的选择,让用户知道为什么这么长时间。
我要添加的唯一另一件事是存储已加载的数据库的布尔值或版本号,因此除非您的应用版本增加,否则无需运行该迁移代码。
通过执行此操作,您可以在App构造函数中放置此布尔检查,并立即加载第一页。如果需要迁移,请加载加载页面,让OnStart完成迁移,然后加载第一个应用程序屏幕。
答案 1 :(得分:0)
另一种方法是将要同时运行的每个项目添加到任务列表中,然后等待所有项目。然后所有项目都将运行异步,但您仍然可以获得CheckUser的结果。我不知道它是否比你使用的更好,但它是另一种方式。否则,如果您正在等待每个功能,那么它们不会同时运行。
protected async Task OnStart()
{
Page startPage = null;
//create a list of the items you want to run concurrently
List<Task> list = new List<Task>();
list.Add(App.Database.Migrations());
list.Add(CheckUser());
//wait for all of them to complete
Task.WaitAll(list.ToArray());
//get the result from the CheckUser call
Task<bool> checkUsertask = list[1] as Task<bool>;
if (checkUsertask.Result == true)
this.MainPage = new Layout.BrowsePage();
else
this.MainPage = new LoginPage();
}
如果您不喜欢列表[1],那么您可以在将其添加到列表之前创建一个任务,这样您就可以在完成后参考它。
protected async Task OnStart()
{
Page startPage = null;
//create a list of the items you want to run concurrently
List<Task> list = new List<Task>();
list.Add(App.Database.Migrations());
var checkUserTask = CheckUser();
//create this task directly so we can refer to it later to get the result
list.Add(checkUserTask);
//wait for all of them to complete
Task.WaitAll(list.ToArray());
//get the result from the CheckUser call
if (checkUserTask.Result == true)
this.MainPage = new Layout.BrowsePage();
else
this.MainPage = new LoginPage();
}