问题
I use ShowLoading() Acr UserDialogs (v5.2.2) on my xamarin forms project (android and ios) but i wont start loader before start await method and Hide Loader with the end.
My code working on ios but on android nothing happened.
example
async Task MyMethod()
{
UserDialogs.Instance.ShowLoading("Loading",MaskType.Black);
await ViewModel.LoadData();
UserDialogs.Instance.HideLoading();
}
//InsideViewModel
public async Task LoadData();
{
await Task.Yield(); //without this code and ios doesnt work
//download data
}
I add for android UserDialogs.Init(this) on MainActivity.cs
Any help please ? Thanks
回答1:
I write some code where is really fast and working perfect with Acr User dialogs.
I use depedency service and here is my full sample code.
PCL code
void CallService ()
{
Device.BeginInvokeOnMainThread (() => UserDialogs.Instance.ShowLoading ("Loading ...", MaskType.Black));
Task.Run (async () => {
await DependencyService.Get<IJsonMethods> ().Load ("SERVICE_URL");
}).ContinueWith (result => Device.BeginInvokeOnMainThread (() => {
UserDialogs.Instance.HideLoading ();
}
})
);
}
Interface
public interface IJsonMethods
{
Task Load(string url);
}
Dependency Service
public async Task Load (string url)
{
try{
using (var http = new HttpClient (new NativeMessageHandler ())) {
var x = await http.GetAsync (new Uri (url));
string res = await x.Content.ReadAsStringAsync ();
MainViewModel.JsonList = JsonConvert.DeserializeObject<ArticleClass.RootObject> (res);
}
}catch (Exception ex) {
MainViewModel.JsonList = null;
}
}
回答2:
I use a more elegant way:
async Task MyMethod()
{
using(UserDialogs.Instance.ShowLoading("Loading",MaskType.Black))
{
await ViewModel.LoadData();
}
}
//InsideViewModel
public async Task LoadData();
{
await Task.Yield(); //without this code and ios doesnt work
//download data
}
回答3:
You should't need to use the await Task.Yield();
.
Please try this:
async Task MyMethod()
{
UserDialogs.Instance.ShowLoading("Loading", MaskType.Black);
await ViewModel.LoadData();
UserDialogs.Instance.HideLoading();
}
//InsideViewModel
public async Task LoadData()
{
await DownloadFileAsync("http://url.to.some/file.mp3", "file.mp3");
}
public async Task DownloadFileAsync(string url, string filename)
{
var destination = Path.Combine(
System.Environment.GetFolderPath(
System.Environment.SpecialFolder.ApplicationData),
filename);
await new WebClient().DownloadFileTaskAsync(new Uri(url), destination);
}
回答4:
This is a common problem. It comes down to the fact that it's often confused that async and await background a Task when in fact all they do is allow better control of long running operations that may be asynchronous in nature. You still need to put your item of work into a separate thread otherwise it might block the UI thread i.e.
async Task MyMethod()
{
UserDialogs.Instance.ShowLoading("Loading",MaskType.Black);
await ViewModel.LoadData();
UserDialogs.Instance.HideLoading();
}
//InsideViewModel
public async Task LoadData();
{
Task.Run(()=> //download data;);
}
I assume MyMethod is within a Page instance and MyMethod is being called on the UIThread via a Command or Click handler.
回答5:
just for ios, you can use ~~ Device.BeginInvokeOnMainThread(new Action(FunctionName));~~ for loading data on UI thread without getting any exception.. I just tried that and it worked. And for using the dialogs, just change Device.BeginInvokeOnMainThread(~~UserDialogs.Instance.ShowLoading()~~) like this and change inside of function accordingly
来源:https://stackoverflow.com/questions/37832860/show-acr-user-dialogs-loader-until-end-of-method-xamarin-forms-android