15

我有一个 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 中每个项目的数组列表。我面临的问题是,在启动活动时,我创建的 ProgressDialog直到onPreExecute()方法完成后才会显示。doInBackground()即我得到一个黑屏,长时间的停顿,然后是一个完全填充的列表,其中包含项目。为什么会发生这种情况?为什么不绘制 UI、显示 ProgressDialog、解析器获取项目并逐步将它们添加到列表中,然后 ProgressDialog 消失?

4

4 回答 4

13

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

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

此处的 get 调用将阻塞 UI 线程(它可能正在关闭此处的任务......),这将阻止任务的 onPreExecute() 方法中的任何 UI 相关内容,直到任务实际完成。哎呀!希望这可以帮助。

于 2010-11-17T14:06:50.377 回答
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();
    }
于 2010-04-24T20:14:11.220 回答
4

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

正确的做法是将Activity实例传递给你AsyncTask的构造函数,并完成你想做的任何事情AsyncTask.onPostExecution()

于 2013-11-17T22:47:19.637 回答
1

如果您在实际 Activity 中对 AsyncTask 进行子类化,则可以使用该onPostExecute方法将后台工作的结果分配给调用类的成员。

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

这样,您的 UI 线程就不会像上面提到的那样被阻塞。但是,您必须注意在子类之外对结果的任何后续使用,因为后台线程可能仍在运行并且您的成员不会具有新值。

于 2011-06-17T18:17:35.917 回答