我有以下问题。我的主要活动包括一个ListView,其中填充了从Web服务获得的数据。首次加载主活动时,如果无法从Web检索数据,我想显示一个带有2个按钮的对话框,“重试”和“取消”。如果用户单击“回复”,则会调用重新加载数据方法,如果有任何异常,则该对话框应再次出现。
我还没有找到一种方法来实现我想要的行为。
@Override
protected void onResume() {
super.onResume();
Log.i("ItemListActivity", "onResume()");
if(isNewInstance) {
reloadItems();
isNewInstance = false;
}
}
private void reloadItems() {
try {
itemService.reloadItems();
items = itemService.getItemList();
listAdapter.notifyDataSetChanged();
} catch (Exception e) {
showDialog(RETRY_DIALOG);
}
}
protected Dialog onCreateDialog(int id) {
switch(id) {
case RETRY_DIALOG:
return new AlertDialog.Builder(this).setTitle(R.string.retryDialog_title)
.setPositiveButton(R.string.retryDialog_retry, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
reloadItems();
}
})
.setNegativeButton(R.string.retryDialog_quit, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create();
}
return null;
}
第一次从onResume()调用reloadItems()并遇到异常时,将显示该对话框。但是当我单击“重试”按钮并且这次从对话框的onclicklistener调用reloadItems()时,对话框不会第二次显示,我猜是因为onclicklistener只会在reloadItems()第二次返回后返回
我试图在onClick()的新线程中运行reloadItems(),但代码仍然在主线程中运行。如果我在新线程中从onResume()运行reloadItems(),代码将在新线程中运行。
调试时我还注意到,只有在reloadItems()返回后,才会在showDialog(RETRY_DIALOG)返回后立即显示对话框。
正如我想要做的那样是非常普遍的行为我确信有一个“最佳实践”解决方案。我对Android完全不熟悉,而且我不习惯这种风格。
答案 0 :(得分:5)
您应该在ASyncTask中运行reloadItems方法。
这些在后台线程中运行您的Web访问和下载过程,并允许您在UI线程上发布UI更新。
您还可以在后台线程中处理异常,然后将更新发布到显示对话框的UI线程。不要忘记在此故障更新后终止您的任务,否则它将继续尝试运行并认为它已成功完成。
同样重要的是,每次运行时都必须创建一个新的INSTANCE任务(例如,重试按钮的onClick监听器就是这样。重用任务会导致异常。