显示Android进度条与Xamarin
本文关键字:Xamarin Android 显示 | 更新日期: 2023-09-27 18:02:41
我正在通过Xamarin/MonoTouch(因此使用c#而不是Java)构建Android应用程序,并希望在应用程序与服务器通信时显示ProgressBar。我一直在尝试使用async来做到这一点,但是我对线程的工作原理没有很好的理解,而且在过去的几个小时里,我一直遇到同样的问题——在我的方法调用之后,而不是之前,ProgressBar显示了。我的代码在OnCreate()方法中,我也将其重写为异步。
loginButton.Click += async (sender, e) =>
{
progbar.Visibility = ViewStates.Visible;
var userFetcher = new UserFetcher();
var json = await userFetcher.FetchUserDetailsAsync(/*parameters*/);
//the above method is async and returns a Task<JsonValue>
ParseUserDetails(json); //another method I created
progbar.Visibility = ViewStates.Invisible;
//do some stuff using the parsed data
};
我遇到的问题是FetchUserDetailsAsync似乎阻塞了我的线程。我一直在通过关闭服务器来测试这一点,因此它需要很长的响应时间(但即使当我测试像Thread.Sleep(5000)这样的东西时,我也有同样的问题)。方法被调用后,它运行progbar.Visibility = ViewStates.Visible;
和progbar.Visibility = ViewStates.Invisible;
一个接一个-我知道这一点,因为当我注释掉不可见部分时,在我的方法得到服务器的"响应"后出现了ProgressBar。编译器也一直在给我提示"跳过67帧!"应用程序可能在其主线程上做了太多的工作。"
就像我之前说的,我没有真正的线程经验,所以很有可能我只是天真地做错了什么。有人能解决这个问题吗?
编辑:这里是FetchUserDetailsAsync的源代码: public async Task<JsonValue> FetchUserDetailsAsync(string url, string username, string password)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
request.ContentType = "application/json";
request.Method = "GET";
string myBasicHeader = AuthenticationHelper.MakeHeader(username, password);
request.Headers.Add("Authorization", "Basic " + myBasicHeader);
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
return jsonDoc;
}
}
}
catch (WebException e)
{
Console.WriteLine(e.ToString());
if (e.Status == WebExceptionStatus.ProtocolError)
{
var response = e.Response as HttpWebResponse;
if (response != null)
{
Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
}
else
{
Console.WriteLine("No http status code available");
}
}
return null;
}
}
看起来FetchUserDetailsAsync或ParseUserDetails正在阻塞UI线程。因为Task.Sleep(5000)是同步运行的。Try await Task.Delay(5000);在FetchUserDetailsAsync行中查看进度条是否显示。如果是,那么你可能需要进入FetchUserDetailsAsync实现确保它实现async
我找到了问题所在。我在FetchUserDetailsAsync方法中调用GetResponse()
而不是GetResponseAsync()
。