【Android】Android中ListView异常:The content of the adapter has changed

来源:互联网 发布:ubuntu添加搜狗输入法 编辑:程序博客网 时间:2024/06/05 00:21

异常描述

E/AndroidRuntime(23093): 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.

字面意思:adapter的内容已经改变,但是ListView并没有收到通知,请确定adapter的内容是否在后台线程(非UI线程)进行了更新。

代码所处环境:开一条新线程连接网络,把服务端返回的数据然存在myArr中,最后使用handler消息通知机制来通知UI主线程,更新UI。

原因及解决方案

出现异常的原因:网络线程可能没有结束(没到handler处理消息函数中),就提前切换到主线程,此时数据源myArr已经不为空,主线程认为数据源加载完毕,会跳到adapter的getView函数中,更新adapter,但并没有通知ListView通知数据源发生变化。

解决方法思路:把数据源的变化、adapter的变化和ListView的变化都放在UI线程中。即把myArr仅作为接收网络数据的buffer,把myArrNew作为数据源。当myArr在其它线程加载完网络数据后(长度不再变化),回调到UI线程,把myArr的内容存到数据源myArrNew,该数据源不再变化,并通知ListView刷新。

再开一个存数据的myArrNew,代码如下

private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        switch (msg.what) {        case NET_SUCCESS:            myArrNew = myArr;            m_adapter.notifyDataSetChanged();              if (startnid != 0) {                m_listView.setPullLoadEnable(true);            }            break;        default:            break;        }    }}

Android ListView控件简介

ListView定义:ListView控件用于以列表的形式来显示数据。该控件采用了MVC模式将前端显示和后端数据进行分离。也就是说,ListView控件在装载数据时,并不是直接使用ListView类的add方法或类似方法添加数据,而是需要一个Adapter对象来为ListView整体适配数据源,进而由ListView展示。这种模式即典型的MVC模式,Adapter对象相当于MVC模式中得C(Control);ListView相当于MVC模式当中的V(View);为ListView提供数据的数组相当于MVC模式中得M(model)。

0 0