在后台线程完成之前,Android ASync任务ProgressDialog不会显示

时间:2010-04-24 00:21:41

标签: android android-asynctask

我有一个Android活动,它从URL抓取RSS源,并使用SAX解析器将XML中的每个项目粘贴到一个数组中。这一切都很好,但正如预期的那样,需要花费一些时间,所以我想在后台使用AsyncActivity来完成它。我的代码如下:

class AddTask extends AsyncTask<Void, Item, Void> {

    protected void onPreExecute() {
        pDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Retrieving data ...", true);
    }

    protected Void doInBackground(Void... unused) {
        items = parser.getItems();

        for (Item it : items) {
            publishProgress(it);
        }
        return(null);
    }

    protected void onProgressUpdate(Item... item) {
        adapter.add(item[0]);
    }

    protected void onPostExecute(Void unused) {
        pDialog.dismiss();
    }
  }

我在onCreate()打电话给

new AddTask().execute();

items = parser.getItems()正常工作 - items是包含XML中每个项目的arraylist。我面临的问题是,在启动活动时,我在onPreExecute()中创建的ProgressDialog在 {/ 1}}方法完成之后才会显示。即我得到一个黑色的屏幕,一个长时间的停顿,然后是一个完整填充列表中的项目。为什么会发生这种情况?为什么不是UI绘图,ProgressDialog显示,解析器获取项目并逐步将它们添加到列表中,然后是ProgressDialog解雇?

4 个答案:

答案 0 :(得分:13)

我怀疑在执行任务后有些东西会阻塞你的UI线程。例如,我见过人们做过这样的事情:

MyTask myTask = new MyTask();
TaskParams params = new TaskParams();
myTask.execute(params);
myTask.get(5000, TimeUnit.MILLISECONDS);

这里的get调用将阻止UI线程(这可能是在这里分离任务...),这将阻止任务的onPreExecute()方法中的任何UI相关内容,直到任务实际完成。哎呦!希望这可以帮助。

答案 1 :(得分:11)

这对我有用

@Override
protected void onPreExecute() {
        dialog = new ProgressDialog(viewContacts.this);
        dialog.setMessage(getString(R.string.please_wait_while_loading));
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }

答案 2 :(得分:4)

这是因为您使用AsyncTask.get()来阻止UI线程“如果需要等待计算完成,然后检索其结果。”。

正确的方法是通过构造函数将Activity实例传递给AsyncTask,并在AsyncTask.onPostExecution()完成您想要执行的操作。

答案 3 :(得分:1)

如果您在实际的Activity中继承了AsyncTask,则可以使用onPostExecute方法将后台工作的结果分配给您的调用类的成员。

如果指定为第三个泛型类型,则结果将作为此方法中的参数传递。

这样,您的UI线程就不会被阻止,如上所述。您必须在子类之外处理结果的任何后续使用,因为后台线程可能仍在运行且您的成员不具有新值。