Android-适配器的内容已更改?

Android-适配器的内容已更改?,android,listview,android-asynctask,Android,Listview,Android Asynctask,我试图让我的无休止的列表工作,但我一直得到关于修改适配器内容的非法状态异常。我完全不知道为什么会这样 这个错误很严重 IllegalStateException: 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

我试图让我的无休止的列表工作,但我一直得到关于修改适配器内容的非法状态异常。我完全不知道为什么会这样

这个错误很严重

IllegalStateException: 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. [in ListView(2131493058, class android.widget.ListView) with Adapter(class ListNewsAdapter)]
以下是我的任务:

public class ListDownloadNewAsyncTask extends AsyncTask<Void, Void, NewsArrayList> {
    private String mLastId = null;

    @Override
    protected void onPreExecute() {
        ListNewsAdapter adapter = (ListNewsAdapter) listView.getAdapter();
        if (adapter != null && adapter.getCount() > 0) {
            mLastId = adapter.getItem(adapter.getCount() - 1).getId();
        }
        super.onPreExecute();
    }

    @Override
    protected NewsArrayList doInBackground(Void... params) {
        NewsArrayList downloadedNews = null;
        try {
            downloadedNews = JSONLoader.loadNews(getActivity(), mLastId);
        } catch (Exception ex) { }
        return downloadedNews;
    }

    @Override
    protected void onPostExecute(NewsArrayList result) {
        mLeftToDownload = result.getLeft();
        ListNewsAdapter adapter = (ListNewsAdapter) listView.getAdapter();
        if (adapter == null) {
            adapter = new ListNewsAdapter(getActivity(), R.layout.news_list_row, result.getNewsArray(), NewsListFragment.this);
            listView.setAdapter(adapter);
        } else {
            adapter.addAll(result.getNewsArray());
            adapter.notifyDataSetChanged();
            isLoading = false;
        }
        super.onPostExecute(result);
    }
}

所以我认为可能是两个任务在同一个适配器上工作。因此,我修改了
onscroll
方法中
if
语句的最后一部分,这减少了崩溃的数量,但我仍然有一些

编辑:@Elltz的Logcat

05-12 00:58:51.027    5108-5108/app.packg E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: 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. [in ListView(2131493058, class android.widget.ListView) with Adapter(class ListNewsAdapter)]
        at android.widget.ListView.layoutChildren(ListView.java:1538)
        at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4385)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
        at android.view.Choreographer.doCallbacks(Choreographer.java:555)
        at android.view.Choreographer.doFrame(Choreographer.java:524)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4849)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
        at dalvik.system.NativeStart.main(Native Method)

好的,在分析代码之后,这似乎是一个有效的解决方案,请尝试以下方法:

1.将此方法添加到适配器

public void addNewData(ArrayList<News> newData) {
    if(news != null) {
        news.addAll(newData);
        notifyDataSetChanged();
    }
}
希望这会有所帮助

编辑显然它不起作用,所以最后的办法是更改适配器

public class ListNewsAdapter extends BaseAdapter {
private final ArrayList<News> news;
private View progressView;
NewsListFragment fragment;

LayoutInflater inflater;

public ListNewsAdapter(Context context, NewsListFragment fragment) {
    this.fragment = fragment;
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    if(news == null)
         return 0;
    return NewsListFragment.isLoading() ? news.size() + 1 : news.size();
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;

    try {
        if (convertView == null || convertView.findViewById(R.id.title) != null || convertView == progressView) {

            convertView = inflater.inflate(R.layout.news_list_row, null);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.description = (TextView) convertView.findViewById(R.id.description);
            holder.image = (ImageView) convertView.findViewById(R.id.news_list_item_image);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (position < getCount()) {
            News newsRow = getItem(position);

            if (newsRow != null) {
                holder.title.setText(newsRow.getTitle().trim().replaceAll("[\n\r]", " "));
                holder.description.setText(newsRow.getDescription().trim().replaceAll("[\n\r]", " "));

                if (newsRow.getPhotoUrl() != null && !newsRow.getPhotoUrl().equalsIgnoreCase("null")) {
                    Ion.with(holder.image).placeholder( R.drawable.icon ).load(newsRow.getPhotoUrl());
                } else {
                    holder.image.setImageResource(R.drawable.icon);
                }
            }
        }
        convertView.setClickable(true);
        convertView.setFocusable(true);
        convertView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Main.instance.changeNewsFragment(news.get(position).getNewsUrl());
            }
        });

        return convertView;

    } catch (IndexOutOfBoundsException e) {
        progressView = inflater.inflate(R.layout.progress_list_item, null);
        return progressView;
    }
}

@Override
public News getItem(int position) {
    return news.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

static class ViewHolder {
    TextView title;
    TextView description;
    ImageView image;
}

public void addNewData(ArrayList<News> newData) {
    if(news == null) {
         news = new ArrayList<News>();
    }
    news.addAll(newData);
    notifyDataSetChanged();
}
}

我希望我没有遗漏任何我刚刚手写的东西,我没有Eclipse。

这个列表是只加载一次,还是不断得到新结果?@DroidChris:list得到了新结果(一旦用户滚动到底部,就会得到一些旧消息)@iravivooda:第一组项被放入适配器的构造函数。显示适配器class@ElJazouli完成,编辑完成。没有任何变化。也许是因为这个观点?我已经把它关掉了,看起来它现在可以工作了。。。
05-12 00:58:51.027    5108-5108/app.packg E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: 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. [in ListView(2131493058, class android.widget.ListView) with Adapter(class ListNewsAdapter)]
        at android.widget.ListView.layoutChildren(ListView.java:1538)
        at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4385)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
        at android.view.Choreographer.doCallbacks(Choreographer.java:555)
        at android.view.Choreographer.doFrame(Choreographer.java:524)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4849)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
        at dalvik.system.NativeStart.main(Native Method)
public void addNewData(ArrayList<News> newData) {
    if(news != null) {
        news.addAll(newData);
        notifyDataSetChanged();
    }
}
@Override
protected void onPostExecute(NewsArrayList result) {
    mLeftToDownload = result.getLeft();
    ListNewsAdapter adapter = (ListNewsAdapter) listView.getAdapter();
    if (adapter == null) {
        adapter = new ListNewsAdapter(getActivity(), R.layout.news_list_row, result.getNewsArray(), NewsListFragment.this);
        listView.setAdapter(adapter);
    } else {
        adapter.addNewData(result.getNewsArray());
        isLoading = false;
    }
    super.onPostExecute(result);
}
public class ListNewsAdapter extends BaseAdapter {
private final ArrayList<News> news;
private View progressView;
NewsListFragment fragment;

LayoutInflater inflater;

public ListNewsAdapter(Context context, NewsListFragment fragment) {
    this.fragment = fragment;
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    if(news == null)
         return 0;
    return NewsListFragment.isLoading() ? news.size() + 1 : news.size();
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;

    try {
        if (convertView == null || convertView.findViewById(R.id.title) != null || convertView == progressView) {

            convertView = inflater.inflate(R.layout.news_list_row, null);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.description = (TextView) convertView.findViewById(R.id.description);
            holder.image = (ImageView) convertView.findViewById(R.id.news_list_item_image);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (position < getCount()) {
            News newsRow = getItem(position);

            if (newsRow != null) {
                holder.title.setText(newsRow.getTitle().trim().replaceAll("[\n\r]", " "));
                holder.description.setText(newsRow.getDescription().trim().replaceAll("[\n\r]", " "));

                if (newsRow.getPhotoUrl() != null && !newsRow.getPhotoUrl().equalsIgnoreCase("null")) {
                    Ion.with(holder.image).placeholder( R.drawable.icon ).load(newsRow.getPhotoUrl());
                } else {
                    holder.image.setImageResource(R.drawable.icon);
                }
            }
        }
        convertView.setClickable(true);
        convertView.setFocusable(true);
        convertView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Main.instance.changeNewsFragment(news.get(position).getNewsUrl());
            }
        });

        return convertView;

    } catch (IndexOutOfBoundsException e) {
        progressView = inflater.inflate(R.layout.progress_list_item, null);
        return progressView;
    }
}

@Override
public News getItem(int position) {
    return news.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

static class ViewHolder {
    TextView title;
    TextView description;
    ImageView image;
}

public void addNewData(ArrayList<News> newData) {
    if(news == null) {
         news = new ArrayList<News>();
    }
    news.addAll(newData);
    notifyDataSetChanged();
}
}
@Override
protected void onPostExecute(NewsArrayList result) {
    mLeftToDownload = result.getLeft();
    ListNewsAdapter adapter = (ListNewsAdapter) listView.getAdapter();
    if (adapter == null) {
        adapter = new ListNewsAdapter(getActivity(), NewsListFragment.this);
        listView.setAdapter(adapter);
    }

    adapter.addNewData(result.getNewsArray());
    isLoading = false;

    super.onPostExecute(result);
}