【问题标题】:Android ASync task ProgressDialog isn't showing until background thread finishesAndroid ASynctask ProgressDialog 在后台线程完成之前不显示
【发布时间】:2010-04-24 00:21:40
【问题描述】:

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

【问题讨论】:

  • 在“解析器获取项目并逐步将它们添加到列表”部分中,缓慢的步骤将出现在解析中,此时您不会向列表中添加任何内容。因此,您的所有项目都会很快进入列表,所以不要指望这里有太多的“增量”效果。
  • 没问题,我并不介意插入的“增量”程度,我只希望 ProgressDialog 在后台工作完成时显示出来,并在完成后消失。

标签: android android-asynctask


【解决方案1】:

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

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

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

【讨论】:

  • 支持提及 task.get 会阻塞用户界面。我需要在某个地方看到它。谢谢!
  • 遇到同样的问题。除了 get() 方法还有什么可以阻塞 UI 线程?
【解决方案2】:

这对我有用

@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();
    }

【讨论】:

  • 这东西真的很有用+1
  • 这与 jackbot 的原始代码有何不同?你只是在做同样的事情,只是稍作改动。
  • 这不是答案。与原代码没有区别。
【解决方案3】:

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

正确的做法是通过构造函数将Activity 实例传递给你的AsyncTask,然后在AsyncTask.onPostExecution() 中完成你想做的任何事情。

【讨论】:

    【解决方案4】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      相关资源
      最近更新 更多