当AsyncTask.get()调用时,ProgressDialog不显示

可能重复:
AsyncTask阻止用户界面威胁,并显示进度条延迟

我想从任何服务器检索JSON时显示progressDialog。 所以我使用AsyncTask作为解决scheme(不确定任何不同的出路)。

一切都很好,ProgressDialog正常工作,直到我使用AsyncTask实例调用.get()方法。 我想这是阻止用户界面。 这是我的AsyncTask:

public class myAsync extends AsyncTask<String, String, List> { String message; // for dialog message ProgressDialog progress; Intent myIntent; Context ctx; public myAsync(String message, Context ctx) { this.message = message; this.ctx = ctx; progress = new ProgressDialog(ctx); } @Override protected void onPreExecute() { progress.setMessage(message); progress.setIndeterminate(true); progress.setCancelable(false); progress.show(); } @Override protected List doInBackground(String... params) { //returns any list after the task return anyList; } @Override protected void onPostExecute(List result) { if(progress.isShowing()) progress.dismiss(); } } 

这里是myActivity这是调用AsyncTask:

 myAsync asyncTask = new myAsync("Loading...", this); asyncTask.execute("Any string", "Other string"); asyncTask.get(); // If I comment out this line, ProgressDialog works 

执行后,当我试图从doInBackground和onPostExecute都logging结果都没有问题。 但是,如果我想用.get()得到结果ProgressDialog没有显示或显示很less的时间(可能是0.2秒)

有什么问题?

是的, get() 必要时等待计算完成,然后检索其结果。 这意味着,你正在阻塞你的UI线程,等待结果。

解决scheme:不要打电话get

通常,你将在postExecute调用一个函数(callback函数)。

调用.get()会将AsyncTask更改为有效的“ SyncTask ”,因为它会导致当前线程(这将是UI线程)等待AsyncTask完成其处理。 由于您现在阻止了UI线程,因此对ProgressDialog.show()方法的调用永远不会有机会让对话框自行绘制屏幕。

删除电话将允许它在后台正常运行。

如果你需要在任务完成后进行处理,我build议你把它放在onPostExecute方法本身中,或者使用onPostExecuteActivity的callback。

如果我正确理解你的问题,你需要在ProgressDialog更新AsyncTask的ProgressDialog ,目前这个function还没有工作。 所以有几件事要注意:我不知道你想用.get()实现什么,但是我假设你想显示进度。

我已经修改了下面的程序,用你的AsyncTask的进度来更新UI线程。 每次您需要更新进度时,请在doInBackground方法中更新该progvariables。

 public class myAsync extends AsyncTask<String, Integer, List> { String message; // for dialog message ProgressDialog progress; Intent myIntent; Context ctx; public myAsync(String message, Context ctx) { this.message = message; this.ctx = ctx; progress = new ProgressDialog(ctx); } @Override protected void onPreExecute() { // Runs on the UI thread progress.setMessage(message); progress.setIndeterminate(true); progress.setCancelable(false); progress.show(); } @Override protected List doInBackground(String... params) { // Runs in the background thread // publish your progress here!! int prog = 5; // This number will represent your "progress" publishProgress(prog); return anyList; } protected void onProgressUpdate(Integer... progress) { // Runs in the UI thread // This method will fire (on the UI thread) EVERYTIME publishProgress // is called. Log.d(TAG, "Progress is: " +progress); } @Override protected void onPostExecute(List result) { // Runs in the UI thread for (int i=0; i<result.size(); i++) { Log.d(TAG, "List item: " + result.get(i)); } if(progress.isShowing()) progress.dismiss(); } } 

尝试使用runOnUiThread像这样:

  runOnUiThread(new Runnable(){ public void run() { dialog.show(); }}); 

在AsyncTask上运行的东西意味着它从UIthread运行,所以通常你不能在asynchronous方法里面运行ui操作,而没有处理器和我通常不用的东西。 我也通过创build一个progressDialog作为我的类上面的一个variables来处理这样的解决scheme,因此它对整个类都是可见的。 然后我在asynctask之前调用progressdialog,然后由于它对整个类的可见性,我在onPostExecute中调用.dissmiss()