【问题标题】:ProgressDialog not showing when thread is busy线程忙时没有显示 ProgressDialog
【发布时间】:2013-11-30 18:11:55
【问题描述】:

我有一些代码 a) 需要大约 10..20 秒来执行 b) 返回一个用于进一步处理的值 c) 由用户通过 UI 操作调用

因此我创建了这样的程序结构:

ProgressDialog pd = new ProgressDialog(ctx);  
pd.setCancelable(false);
pd.setCanceledOnTouchOutside(false);
pd.setTitle(ctx.getResources().getText(R.string.progress));
pd.setMessage(ctx.getResources().getText(R.string.wait_keygen));
pd.setIndeterminate(true);
pd.show();

returnValue=doSomeDifficultCalculationsHere();

pd.dismiss();

现在我的问题是:进度对话框没有显示,它似乎也被阻塞的 doSomeDifficultCalculationsHere() 函数阻塞了。

当我将 doSomeDifficultCalculationsHere() 放入自己的线程并执行 Thread.join() 以等待此函数的结果时,由于 Thread.join() 阻塞,因此也不会显示进度对话。

当我将 ProgressDialog 放入线程时,我得到一个异常。

那么,当我无法真正异步调用 doSomeDifficultCalculationsHere() 因为后续所有步骤都需要它的结果时,我还能如何解决这个问题并让 ProgressDialog 显示?

谢谢!

【问题讨论】:

  • 您希望您的用户盯着ProgressDialog 20-30 秒?您可能需要重新考虑...

标签: android multithreading progressdialog


【解决方案1】:

首先,使用DialogFragments来显示Dialogs。 其次,使用 AsyncTask 启动该 DialogFragment,如 cmets 中所述。有在 MainThread 上运行的 onPreExecute(...) 和 onPostExecute(ReturnType) 方法。使用这些回调来显示/隐藏您的对话框。这可以通过以下方式完成:

dialogFragment = new MyGreatProgressDialogFragment();
dialogFragment.show(getFragmentManager(), "");
...
dialogFragment.dismiss();

您还可以使用事件来显示/关闭对话框。我可以推荐 GreenRobot 的 EventBus (https://github.com/greenrobot/EventBus)。

正如@codeMagic 已经提到的,让用户等待 30 秒是非常糟糕的风格。有几个认为你可以做的。 尽量不要通过对话框阻止用户。在您的应用程序的某处显示 ProgressBar。如果除了让用户等待之外没有其他可能性,您还可以在通知栏中显示通知,以明确用户可以离开您的应用程序并且该过程将继续运行。只需确保用户可以做的不仅仅是等待过程完成。

【讨论】:

    【解决方案2】:

    我建议您使用 AsyncTask 以便用户可以在不中断工作流程的情况下离开您的应用程序,这里有一个如何执行此操作的示例:

    class startWorkFlow extends AsyncTask<String, Void, Integer> {
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd.setCancelable(false);
            pd.setCanceledOnTouchOutside(false);
            pd.setTitle(ctx.getResources().getText(R.string.progress));
            pd.setMessage(ctx.getResources().getText(R.string.wait_keygen));
            pd.setIndeterminate(true);
            pd.show();
        }
    
        @Override
        protected Integer doInBackground(String... args ) {
            return doSomeDifficultCalculationsHere();
        }
        protected void onPostExecute(Integer i) {
            pd.dismiss();
            continueWorkFlowWith(i);
        }
    }
    

    并调用它:

     new startWorkFlow().execute();
    

    确保doSomeDifficultCalculationsHere() 不使用活动中的变量;如果是这种情况,您必须将一些参数传递给 AsyncTask。

    【讨论】:

      猜你喜欢
      • 2017-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 2013-02-13
      • 2015-08-04
      相关资源
      最近更新 更多