Xamarin 中的错误 Android 带有进度对话框“只有创建视图层次结构的原始线程才能触及它的视图”
Error in Xamarin Android with a progress dialog “Only the original thread that created a view hierarchy can touch its views”
我正在尝试使用进度对话框,同时填充数据网格,但出现以下错误:"Only the original thread that created a view hierarchy can touch its views",这是我的代码,希望他们能帮助我
public async void RelacionClientesREST()
{
try
{
var dlg = ProgressDialog.Show(this, "Loading", "Cargando relación de usuarios");
ThreadPool.QueueUserWorkItem(d => {
RestClient client = new RestClient("http://portalclientewa.azurewebsites.net/api/RelacionClientes/");
var request = new RestRequest("GetData", Method.GET);
request.Timeout = 1500000;
request.RequestFormat = DataFormat.Json;
request.AddParameter("idP", Idp);
var temp = client.Execute(request).Content;
var parsedJson = JsonConvert.DeserializeObject(temp).ToString();
var lst = JsonConvert.DeserializeObject<List<ClientesProp>>(parsedJson).ToList();
dataGrid.ItemsSource = lst;
RunOnUiThread(() => {
dlg.Dismiss();
});
});
}
catch (Exception ex)
{
Toast.MakeText(this, "No hay datos registrados", ToastLength.Short).Show();
}
}
错误告诉您应用的 UI 必须由主线程处理。在您的代码中,您在后台线程 (ThreadPool.QueueUserWorkItem) 上 运行 一些代码,而这些代码需要在 UI 线程 (RunOnUiThread) 上 运行。
您不能使用 dlg.Dismiss();在 ThreadPool.QueueUserWorkItem 内,在尝试关闭符号
之前移动它
为什么不改用 Task?
Task.Run(() => doStuff("hello world"));
它看起来并没有好很多,但至少它没有未使用的标识符。
注意:Task.Run() 是 .Net 4.5 或更高版本。如果您使用的是 .Net 4,则必须执行以下操作:
Task.Factory.StartNew(() => doStuff("hello world"));
以上两者都使用了线程池。
Only the original thread that created a view hierarchy can touch its views
正如@CaPorter 所说,应用程序的UI 必须由主线程处理。 There are any number of ways to get code to execute on the UI thread,你可以尝试使用 Looper.MainLooper
和 Handler.Post()
。
像这样修改您的代码:
ThreadPool.QueueUserWorkItem(d => {
...
Handler handler = new Handler(Looper.MainLooper);
Action action = () =>
{
dataGrid.ItemsSource = lst;
dlg.Dismiss();
};
handler.Post(action);
});
我正在尝试使用进度对话框,同时填充数据网格,但出现以下错误:"Only the original thread that created a view hierarchy can touch its views",这是我的代码,希望他们能帮助我
public async void RelacionClientesREST()
{
try
{
var dlg = ProgressDialog.Show(this, "Loading", "Cargando relación de usuarios");
ThreadPool.QueueUserWorkItem(d => {
RestClient client = new RestClient("http://portalclientewa.azurewebsites.net/api/RelacionClientes/");
var request = new RestRequest("GetData", Method.GET);
request.Timeout = 1500000;
request.RequestFormat = DataFormat.Json;
request.AddParameter("idP", Idp);
var temp = client.Execute(request).Content;
var parsedJson = JsonConvert.DeserializeObject(temp).ToString();
var lst = JsonConvert.DeserializeObject<List<ClientesProp>>(parsedJson).ToList();
dataGrid.ItemsSource = lst;
RunOnUiThread(() => {
dlg.Dismiss();
});
});
}
catch (Exception ex)
{
Toast.MakeText(this, "No hay datos registrados", ToastLength.Short).Show();
}
}
错误告诉您应用的 UI 必须由主线程处理。在您的代码中,您在后台线程 (ThreadPool.QueueUserWorkItem) 上 运行 一些代码,而这些代码需要在 UI 线程 (RunOnUiThread) 上 运行。
您不能使用 dlg.Dismiss();在 ThreadPool.QueueUserWorkItem 内,在尝试关闭符号
之前移动它为什么不改用 Task?
Task.Run(() => doStuff("hello world"));
它看起来并没有好很多,但至少它没有未使用的标识符。
注意:Task.Run() 是 .Net 4.5 或更高版本。如果您使用的是 .Net 4,则必须执行以下操作:
Task.Factory.StartNew(() => doStuff("hello world"));
以上两者都使用了线程池。
Only the original thread that created a view hierarchy can touch its views
正如@CaPorter 所说,应用程序的UI 必须由主线程处理。 There are any number of ways to get code to execute on the UI thread,你可以尝试使用 Looper.MainLooper
和 Handler.Post()
。
像这样修改您的代码:
ThreadPool.QueueUserWorkItem(d => {
...
Handler handler = new Handler(Looper.MainLooper);
Action action = () =>
{
dataGrid.ItemsSource = lst;
dlg.Dismiss();
};
handler.Post(action);
});