Android ProgressDialog仅显示一瞬间

Android ProgressDialog仅显示一瞬间,android,Android,编辑:这与 我确保在网络通信和文件操作中使用AsyncTasks,在任务完成之前显示一个不确定的、可取消的ProgressDialog,我觉得我应该这样做 在某些情况下——移动互联网连接速度慢,旧设备动力不足——这可能需要几秒钟的时间。但是,在其他情况下或在其他设备上,完全相同的任务可能会很快完成,导致ProgressDialog仅显示一小部分瞬间,基本上在屏幕上闪烁 这里的最佳实践是什么?我可以想出几个选择: 让它保持原样,知道有些用户会有这种闪烁的效果 强制ProgressDialog在消失

编辑:这与

我确保在网络通信和文件操作中使用AsyncTasks,在任务完成之前显示一个不确定的、可取消的ProgressDialog,我觉得我应该这样做

在某些情况下——移动互联网连接速度慢,旧设备动力不足——这可能需要几秒钟的时间。但是,在其他情况下或在其他设备上,完全相同的任务可能会很快完成,导致ProgressDialog仅显示一小部分瞬间,基本上在屏幕上闪烁

这里的最佳实践是什么?我可以想出几个选择:

  • 让它保持原样,知道有些用户会有这种闪烁的效果
  • 强制ProgressDialog在消失之前保持可见的最短时间(半秒,一秒),即使任务已经完成——但我讨厌引入人为延迟的想法
  • 为任务计时,并且仅当任务花费的时间超过最小设置时间量(如半秒)时才显示ProgressDialog。问题是这并不是一个真正的解决方案;如果任务在这段时间内完成,那就太好了;如果任务需要很长时间,很好——但是如果最短时间为0.5秒,而任务实际需要0.7秒,那么您又会遇到同样的问题。。。短暂的闪烁
  • 如果您可以监控任务的进度,请对其进行简要测试,并从第一秒的分数或第一个x%估算完成任务所需的时间;如果预计需要一段时间,则显示ProgressDialog。但这将是相当复杂的,并且不是每个背景任务都适合于这种进度评估

  • 最好的方法是什么?有没有我错过的选择?是否有办法设置ProgressDialog,使其仅显示是否有明显的延迟?(我怀疑有,但如果有什么神奇的方法就好了)。其中一个是“标准”解决方案吗?

    保持进度对话框的原样,尤其是对于网络操作,因为在开发环境中您可能会很幸运,但也因为您无法控制在真实场景中internet连接的工作速度。

    多亏了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毫秒),则不会显示对话框。如果需要更长时间,则会在延迟后显示。请注意,这并不能完全防止“闪烁”。。。例如,如果任务耗时1秒,则对话框将闪烁半秒

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

    强制ProgressDialog在最短时间内保持可见 (半秒,一秒)在它消失之前,即使任务 已经完成了——但我讨厌引入人工智能的想法 耽搁

    这是一个比让进度对话框在屏幕上短暂闪烁更好的解决方案。从用户的角度来看,它引入了一致性。如果它在某些时候出现,而不是在其他时候出现,则似乎有些东西工作不正常

    我在异步任务中添加了一个长变量,并在预执行时将其设置为System.nanoTime()。然后在post execute中,我计算经过的时间,并将其与设定的最短时间进行比较。如果在该时间段内,我将使用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();
        }
    
    }
    
    私有最终类SyncPendingOrders扩展异步任务{
    长定时器=0;
    @凌驾
    受保护的void onPreExecute(){
    计时器=System.nanoTime();
    pd=ProgressDialog.show(上下文,null,“更新挂起的订单”,true,false);
    pd.setIndeterminatedRavable(context.getResources().getDrawable(R.anim.spinner));
    }
    @凌驾
    受保护的字符串doInBackground(字符串…args){
    updatePendingOrders();
    返回null;
    }
    @凌驾
    受保护的void onPostExecute(字符串me){
    长时钟=System.nanoTime()-计时器-2000000000;
    如果(时钟>0)
    {
    试一试{
    等待(时钟);
    }捕获(可丢弃的e){
    }
    }
    PendingOrderView();
    pd.解散();
    }
    }
    

    这样,用户总是看到同一个框,知道程序在做什么。一致性是关键。

    没有标准的方法,您的想法都是正确的。显示ProgressDialog,然后在一个小延迟(例如100ms)后运行AsyncTask不是一个糟糕的方法。你也可以做一个PrimeStBar(即SPEnter),一个比对话框小的更微妙的UI元素。我同意CSmith,我会考虑把它从DILAN中取出,并把它添加到某个UI上。这样就不会产生不和谐,但在需要时它仍然存在。