0

尝试从异步任务更新我的片段中的列表视图时出现此类错误:

The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.

我的 AsyncTask 类

protected Void doInBackground(Void... params) {
        int nextStep;
        BaseAnt tempAnt = null;
        ArrayList<BaseAnt> antList = new ArrayList<BaseAnt>();
        while (true) {
            Log.d("myLogs", "Start from APP");
            nextStep = RandomNumber.getRandomNumber(3);
            switch (nextStep) {
            case 0:
                tempAnt = new GuardAnt();
                AppStat.addToLog("Guard");
                break;
            case 1:
                tempAnt = new MotherAnt();
                AppStat.addToLog("Mother born");
                break;
            case 2:
                tempAnt = new WorkerAnt();
                AppStat.addToLog("Worker born");
                break;
            default:
                break;
            }
            antList.add(tempAnt);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            for (int i = 0; i < antList.size(); i++)
                antList.get(i).eat();
            publishProgress(String.valueOf(AppStat.WATER));
            if (AppStat.WATER < 0)
                break;
        }
        return null;

    }

    protected void onPostExecute(String result) {

    }

    @Override
    protected void onProgressUpdate(String... values) {
        Log.d("myLogs", "onProgressUpdate");
        LogFragment.mLogAdapter.notifyDataSetChanged();
        LogFragment.mLogAdapter.setSelectToLast();
        StatFragment.tvWater.setText(String.valueOf(AppStat.WATER));
        super.onProgressUpdate(values);
    }

AppStat 是类扩展应用程序,包含有关我需要的变量和方法的信息

    public static void addToLog(String str) {
    if (listLog.size() > 256)
        listLog.remove(0);
    listLog.add(getNowtime() + ": " + str);
}

在 LogAdapter 扩展 BaseAdapter:

    public void setSelectToLast() {
    Log.d("myLogs","UpdateToLast");
    notifyDataSetChanged();
    LogFragment.lvList.setSelection(getCount() + 1);
}

如何解决?

4

5 回答 5

2

您不应在 doInBackground() 中调用 addToLog()(或任何其他 UI 操作)。要么在 doInBackground 中收集所有内容,将其作为结果返回,然后在 onPostExecute 中更新列表,要么使用 publishProgress() 并在 onProgressUpdate() 中更改列表内容...

onPostExecute 和 onProgressUpdate 在 UI 线程中执行,doInBackground 在不同的线程中执行。

于 2013-11-11T14:27:13.450 回答
1

UI 更新是通过 asynctask 中的 onpostexecute() 方法完成的。这样做,它会正常工作,因为在 doinbackground () 完成工作后 onpostexecute 在 ui 线程上运行。

于 2013-11-11T14:29:11.553 回答
0

您应该使用以下内容在主线程中运行更新:

MainActivity.this.runOnUiThread(new runnable(){
public void run(){
    Log.d("UI thread", "I am the UI thread");
}

});

您还可以查看这篇文章: Android 基础:在 UI 线程中运行代码

于 2013-11-11T14:24:21.083 回答
0

尝试使用

MainActivity.this.runOnUiThread(new runnable()
{
  public void run()
  {
    LogFragment.mLogAdapter.notifyDataSetChanged();
    LogFragment.mLogAdapter.setSelectToLast();
    StatFragment.tvWater.setText(String.valueOf(AppStat.WATER));
  }
}

在你的onProgressUpdate方法中

于 2013-11-11T14:27:01.350 回答
0

尝试在 onPostExecute 中调用适配器上的 notifyDataSetChanged()。

于 2013-11-11T14:27:13.237 回答