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