编辑:这与ProgressDialog doesn't show just flashes
不同我确保使用AsyncTasks进行网络通信和文件操作,显示一个不确定的,可取消的ProgressDialog,直到任务完成,因为我觉得我应该正确。
在某些情况下 - 移动互联网速度较慢,设备功能较低的设备 - 可能需要几秒钟。但是完全相同的任务可能在其他情况下或在其他设备上非常快速地完成,导致ProgressDialog仅在瞬间显示,基本上在屏幕上闪烁。
这里的最佳做法是什么?我可以想到几个选择:
最好的方法是什么?有没有我错过的选项?有没有办法设置ProgressDialog所以它只显示是否会有明显的延迟? (我怀疑它有,但如果有一些神奇的方式会很好)。其中一种是“标准”解决方案吗?
答案 0 :(得分:2)
强制ProgressDialog在最短时间内保持可见状态 (半秒,一秒)它消失之前,即使任务已经消失 已经完成 - 但我讨厌引入人工的想法 延迟。
这比使进度对话框在屏幕上短暂闪烁更好。从用户角度来看,它引入了一致性。如果它出现了一些而不是其他,似乎某些东西不能正常工作。
我在我的异步任务中添加了一个long变量,并在预执行时将其设置为System.nanoTime()。然后在后执行中我计算通过了多少时间并将其与设定的最小时间进行比较。如果它在这段时间内,我使用wait()表示剩余时间。目前我将它设置为1.5秒延迟,以确保有足够的时间在消失前读取进度对话框。
private final class SyncPendingOrders extends AsyncTask<String, Integer, String> {
long timer = 0;
@Override
protected void onPreExecute(){
timer = System.nanoTime();
pd = ProgressDialog.show(context,null,"Updating Pending Orders",true,false);
pd.setIndeterminateDrawable(context.getResources().getDrawable(R.anim.spinner));
}
@Override
protected String doInBackground(String... args) {
updatePendingOrders();
return null;
}
@Override
protected void onPostExecute(String me){
long clock = System.nanoTime()-timer - 2000000000;
if(clock > 0)
{
try{
wait(clock);
}catch(Throwable e){
}
}
PendingOrdersView();
pd.dismiss();
}
}
这样,用户始终可以看到同一个框,并知道程序在做什么。一致性是关键。
答案 1 :(得分:0)
保持进度对话框不变,特别是对于网络操作,因为您可能在开发环境中变得幸运,但也因为您无法控制互联网连接在现实世界中的工作速度
答案 2 :(得分:0)
感谢CSmith的建议,我尝试将其添加到我的AsyncTask中,完成所有后台工作:
@Override
protected void onCancelled() {
completed = true;
super.onCancelled();
dismissProgressDialog(); //calls handler.post and dismisses dialog
}
@Override
protected void onPostExecute(Void result) {
completed = true;
super.onPostExecute(result);
dismissProgressDialog();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
return;
}
handler.post(new Runnable() {
@Override
public void run() {
if (!completed) {
progressDialog = ProgressDialog.show(activity, activity.getString(R.string.loading_title), null, true, true, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
cancel(true);
}
});
}
}
});
}
}).start();
}
如果任务在比指示的延迟(500毫秒,在这种情况下)更短的时间内完成,则不显示该对话框。如果需要更长时间,则会在延迟后显示。请注意,这并不能完全阻止“闪烁”...例如,如果任务花了一秒钟,那么对话框会闪烁半秒钟。
这似乎有所帮助,但我对解决方案和欢迎建议并不完全满意。