我有一个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解雇?
答案 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线程就不会被阻止,如上所述。您必须在子类之外处理结果的任何后续使用,因为后台线程可能仍在运行且您的成员不具有新值。