2017-09-15 20 views
0

执行异步任务,我想执行下一次使用Xamarin:上启动

  • 当应用程序启动时启动画面立即呈现(我已经达到了这个以下一个教程https://channel9.msdn.com/Blogs/MVP-Windows-Dev/Using-Splash-Screen-with-Xamarin-Forms

  • 执行数据库迁移如果有(用户更新的应用程序,并在第一次运行)

  • 从数据库中读取用户数据(用户名和密码),调用REST webservice来检查用户数据是否仍然有效。如果用户的数据是有效的将用户重定向到炫魅否则重定向到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。我知道异步void不会等待,如果它不明确地有.Wait()- Async void,但这是否意味着执行线程仍然继续它的工作。

执行线程命中时await App.Database.Migrations();它暂停执行并等待等待Task完成。同时它继续它的工作(即LoadApplication()继续执行,并期望现在设置App.MainPage)。我的假设是否正确?对于异步/等待我来说,我很新。

我只是想避免LoadingPage因为三分屏显示:

  • 闪屏(权当应用程序被启动)
  • LoadingPage(DB迁移,HTTP请求,..)
  • BrowsePage或LoginPage

对于用户体验而言,理想的只是两页。

我弄成这个样子,但我相信有一个更好的方法:

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

你在'更好的方法'中寻找什么?为什么你认为显示一个加载页面是一个劣质的用户体验? –

+0

我想,如果应用程序需要5-8秒加载然后加载页面就可以了。它向用户显示正在发生的事情(正在进行迁移......)。我测量了时间,启动应用程序需要7秒(Samsung Galaxy A5)。 – broadband

回答

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(); 
} 
+0

的OP正在更新数据库,如果需要的话,并从中获取_then_用户信息。两者不能同时运行,一个取决于另一个。 –

1

那么你可以把一切都变成了应用程序的构造,以及溅射屏幕只会显示一个较长的,同时加载的应用程序,但实际上我相信这是一个劣解。

有一个闪屏,然后加载页面,看起来酷似溅射屏幕,但有一个进度条,或加载图标,告诉它是做什么的用户,是一个更好的方法。

如果你必须在用户看到第一页之前这样做,那么加载屏幕是一个很好的选择,让用户知道为什么它需要这么长时间。

我想补充的唯一的另一件事,是存储已经加载数据库的布尔或版本号,这样你就不会需要运行迁移代码,除非你的应用程序的版本增加。

通过这样做,你可以把这个布尔检查你的应用程序的构造函数,并加载第一页,立竿见影。如果需要迁移,然后加载页面加载,并让的OnStart完成迁移,然后加载第一个应用程序的屏幕。