Xamarin.Android 在后台线程上使用异步方法导致屏幕闪烁
Xamarin.Android using async method on background thread causes screen flash
所以我正在尝试为我正在创建的应用程序创建一个 loading/splash 屏幕。基本上,如果用户未通过身份验证,则他们不应该能够访问应用程序的其他部分。此外,我希望该应用程序在加载主 activity.
之前尝试同步必要的数据库对象
问题是,当我调用 Authenticate() 方法和 InitLocalStoreAsync() 方法时,屏幕闪烁(几乎就像 activity 重新加载,或者应用程序正在做我不做的事情了解在执行方法时隐藏了 activity)。我不希望这种情况发生。
我是 Android App Dev 的新手,甚至是 Xamarin 的新手。
我正在使用来自 Azure 移动服务身份验证等教程的修改代码
我是否应该使用 RunOnUiThread 以某种方式执行这些方法?如果是这样,我如何与 RunOnUiThread 一起等待?或者我应该以完全不同的方式来做这件事吗?
我很迷茫。我试图搜索并找到要遵循的教程,但我似乎找不到答案。这是到目前为止的代码:
protected override async void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Activity_Splash);
// Create your application here
try{
CurrentPlatform.Init ();
// Create the Mobile Service Client instance, using the provided
// Mobile Service URL and key
client = new MobileServiceClient (applicationURL, applicationKey);
statusText = FindViewById<TextView> (Resource.Id.SplashStatusText);
ThreadPool.QueueUserWorkItem(x => Initialize());
}catch(Java.Net.MalformedURLException){
CreateAndShowDialog (new Exception ("There was an error creating the Mobile Service. Verify the URL"), "Error");
}catch(Exception e) {
CreateAndShowDialog (e, "Error");
}
}
private async void Initialize()
{
RunOnUiThread(() => statusText.Text = "Authenticating...");
await Authenticate();
RunOnUiThread (() => statusText.Text = "Syncing...");
await InitLocalStoreAsync();
MoveToMainActivity();
}
private async Task Authenticate()
{
try
{
user = await client.LoginAsync(this, MobileServiceAuthenticationProvider.Google);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private async Task InitLocalStoreAsync()
{
// new code to initialize the SQLite store
string path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), localDbFilename);
if (!File.Exists(path))
{
File.Create(path).Dispose();
}
var store = new MobileServiceSQLiteStore(path);
store.DefineTable<ToDoItem>();
// Uses the default conflict handler, which fails on conflict
// To use a different conflict handler, pass a parameter to InitializeAsync. For more details, see http://go.microsoft.com/fwlink/?LinkId=521416
await client.SyncContext.InitializeAsync(store);
}
我该如何重组它,以免出现任何屏幕闪烁?
如果您想运行一个异步方法,您必须使用任务工厂:
RunOnUiThread(() => statusText.Text = "Loading.");
Task.Run(() => AsyncWork()).ContinueWith(result => RunOnUiThread(() => statusText.Text = "Done!"));
屏幕闪烁我认为可能是两件事,应用程序崩溃并正在尝试恢复最后一个 activity 或者您正在尝试更新 UI 线程上的元素并执行 processing/work 也是,所以它可能是 "stutter".
所以我正在尝试为我正在创建的应用程序创建一个 loading/splash 屏幕。基本上,如果用户未通过身份验证,则他们不应该能够访问应用程序的其他部分。此外,我希望该应用程序在加载主 activity.
之前尝试同步必要的数据库对象问题是,当我调用 Authenticate() 方法和 InitLocalStoreAsync() 方法时,屏幕闪烁(几乎就像 activity 重新加载,或者应用程序正在做我不做的事情了解在执行方法时隐藏了 activity)。我不希望这种情况发生。
我是 Android App Dev 的新手,甚至是 Xamarin 的新手。
我正在使用来自 Azure 移动服务身份验证等教程的修改代码
我是否应该使用 RunOnUiThread 以某种方式执行这些方法?如果是这样,我如何与 RunOnUiThread 一起等待?或者我应该以完全不同的方式来做这件事吗?
我很迷茫。我试图搜索并找到要遵循的教程,但我似乎找不到答案。这是到目前为止的代码:
protected override async void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Activity_Splash);
// Create your application here
try{
CurrentPlatform.Init ();
// Create the Mobile Service Client instance, using the provided
// Mobile Service URL and key
client = new MobileServiceClient (applicationURL, applicationKey);
statusText = FindViewById<TextView> (Resource.Id.SplashStatusText);
ThreadPool.QueueUserWorkItem(x => Initialize());
}catch(Java.Net.MalformedURLException){
CreateAndShowDialog (new Exception ("There was an error creating the Mobile Service. Verify the URL"), "Error");
}catch(Exception e) {
CreateAndShowDialog (e, "Error");
}
}
private async void Initialize()
{
RunOnUiThread(() => statusText.Text = "Authenticating...");
await Authenticate();
RunOnUiThread (() => statusText.Text = "Syncing...");
await InitLocalStoreAsync();
MoveToMainActivity();
}
private async Task Authenticate()
{
try
{
user = await client.LoginAsync(this, MobileServiceAuthenticationProvider.Google);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private async Task InitLocalStoreAsync()
{
// new code to initialize the SQLite store
string path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), localDbFilename);
if (!File.Exists(path))
{
File.Create(path).Dispose();
}
var store = new MobileServiceSQLiteStore(path);
store.DefineTable<ToDoItem>();
// Uses the default conflict handler, which fails on conflict
// To use a different conflict handler, pass a parameter to InitializeAsync. For more details, see http://go.microsoft.com/fwlink/?LinkId=521416
await client.SyncContext.InitializeAsync(store);
}
我该如何重组它,以免出现任何屏幕闪烁?
如果您想运行一个异步方法,您必须使用任务工厂:
RunOnUiThread(() => statusText.Text = "Loading.");
Task.Run(() => AsyncWork()).ContinueWith(result => RunOnUiThread(() => statusText.Text = "Done!"));
屏幕闪烁我认为可能是两件事,应用程序崩溃并正在尝试恢复最后一个 activity 或者您正在尝试更新 UI 线程上的元素并执行 processing/work 也是,所以它可能是 "stutter".