当线程忙时,ProgressDialog不显示

时间:2013-11-17 16:57:18

标签: android multithreading progressdialog

我有一些代码 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,因为以下所有步骤都需要它的结果?

谢谢!

2 个答案:

答案 0 :(得分:0)

首先,使用DialogFragments显示对话框。 其次,使用AsyncTask启动注释中提到的DialogFragment。在MainThread上运行的方法有onExreExecute(...)和onPostExecute(ReturnType)。使用这些回调来显示/隐藏对话框。这可以通过以下方式完成:

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

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

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

答案 1 :(得分:0)

我建议您使用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。