从后台线程更新适配器

时间:2014-09-30 15:52:46

标签: java android

我的一些用户(可能是50个)因以下错误而崩溃:

  

java.lang.IllegalStateException:适配器的内容有   已更改,但ListView未收到通知。确保   您的适配器的内容不会从后台线程修改,但是   仅来自UI线程。

如果我理解正确,是因为在AsyncTask的adapter.clear();方法中调用adapter.addAll(list);doInBackground()而导致的,我需要将其移到{ {1}}。

问题是我无法重现该错误,所以我无法确定它是否已修复。 StackOverflow上的一些类似问题似乎表明,简单地将适配器更新为onPostExecute()方法并不能解决问题。

有没有人知道如何在我的设备上每次都能发生此错误,以确保修复工作正常?我不明白为什么它在大多数情况下会起作用,但有时只会导致崩溃。

4 个答案:

答案 0 :(得分:1)

简单回答:您忘记致电adapter.notifyDatasetChanged()

  

通知附加的观察者基础数据已经存在   已更改,任何反映数据集的视图都应自行刷新。

在后台获取您的数据并在onPostExecute()中更新您的适配器,因为您永远不应该从后台线程更改适配器的内容。 {0} {}和onPreExecute()都在UI线程上执行。

答案 1 :(得分:0)

要重现此问题,请在doInBackground()中更改适配器后尝试休眠。

例如:

  @Override
  protected Void doInBackground(Void... params) {
    adapter.clear();
    try
    {
       Thread.sleep(5000);
    }
    catch(InterruptedException e){}
    return null;
  }

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    adapter.notifyDatasetChanged();
  }

答案 2 :(得分:0)

您不应该在doInBackground(..)方法中调用任何UI内容。 只需在onPostExecute(..)和onPreExecute(..)

中调用它们

例如

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    adapter.clear();
  }

根据AsyncTask文档,在“4个步骤”段落中。

  

onPostExecute(Result),在后台后的UI线程上调用   计算结束。背景计算的结果是   作为参数传递给此步骤。

答案 3 :(得分:0)

试试这个..

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                     adapter.notifyDatasetChanged();
                }
            });