ProgressDialog仅显示瞬间

时间:2012-03-02 21:50:04

标签: android

编辑:这与ProgressDialog doesn't show just flashes

不同

我确保使用AsyncTasks进行网络通信和文件操作,显示一个不确定的,可取消的ProgressDialog,直到任务完成,因为我觉得我应该正确。

在某些情况下 - 移动互联网速度较慢,设备功能较低的设备 - 可能需要几秒钟。但是完全相同的任务可能在其他情况下或在其他设备上非常快速地完成,导致ProgressDialog仅在瞬间显示,基本上在屏幕上闪烁。

这里的最佳做法是什么?我可以想到几个选择:

  1. 保持原样,知道有些用户会产生闪烁效果。
  2. 强制ProgressDialog在消失之前保持可见的最短时间(半秒,一秒),即使任务已经完成 - 但我讨厌引入人为延迟的想法。
  3. 为任务计时,仅在任务需要超过最小设定时间(例如半秒)时显示ProgressDialog。问题是这不是一个真正的解决方案;如果任务需要在那段时间内完成,那就太好了;如果任务需要很长时间,那么很好 - 但如果最短时间为0.5秒且任务实际需要0.7秒,那么你再次遇到同样的问题......短暂的闪烁。
  4. 如果您可以监控任务的进度,请对其进行简要测试,并从最初的一分之一或前一个x%开始估算完成任务所需的时间;如果预计需要一段时间,则显示ProgressDialog。但这将是相当复杂的,并非所有后台任务都适合这种进度估算。
  5. 最好的方法是什么?有没有我错过的选项?有没有办法设置ProgressDialog所以它只显示是否会有明显的延迟? (我怀疑它有,但如果有一些神奇的方式会很好)。其中一种是“标准”解决方案吗?

3 个答案:

答案 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毫秒,在这种情况下)更短的时间内完成,则不显示该对话框。如果需要更长时间,则会在延迟后显示。请注意,这并不能完全阻止“闪烁”...例如,如果任务花了一秒钟,那么对话框会闪烁半秒钟。

这似乎有所帮助,但我对解决方案和欢迎建议并不完全满意。