android 修改listview中adapter数据时抛出异常java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification问题

近日在做项目时遇到非必现crush,具体异常信息为:

// Short Msg: java.lang.IllegalStateException

// Long Msg: 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(2131624004, class android.widget.ListView) with
Adapter(class com.baidu.smartcalendar.widget.cx)]

// Build Label:
Coolpad/pxa1088dkb_def/8750:4.2.1/JOP40D/4.2.063.P1.131218.8750:user/release-keys

// Build Changelist: 4.2.016.P1.8750

// Build Time: 1387361194000

// 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(2131624004, class android.widget.ListView) with Adapter(class
com.baidu.smartcalendar.widget.cx)]

// at android.widget.ListView.layoutChildren(ListView.java:1559)

// at
android.widget.AbsListView.onTouchModeChanged(AbsListView.java:3313)

// at
android.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver.java:712)

// at
android.view.ViewRootImpl.ensureTouchModeLocally(ViewRootImpl.java:3078)

// at
android.view.ViewRootImpl.ensureTouchMode(ViewRootImpl.java:3062)

// at
android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3206)

// at
android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3169)

// at
android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4300)

// at
android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4279)

// at
android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4371)

// at
android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)

// at android.os.MessageQueue.nativePollOnce(Native Method)

// at android.os.MessageQueue.next(MessageQueue.java:125)

// at android.os.Looper.loop(Looper.java:124)

// at android.app.ActivityThread.main(ActivityThread.java:5078)

// 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:856)

// at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:623)

// at dalvik.system.NativeStart.main(Native Method)

异常的描述是不要在其他线程中修改listview的adapter数据而在ui线程中进行刷新notifyDataSetChanged()。我们一般为adapter添加数据时常常使用activity类内部的全局变量,这时在外部或其他线程中更新数据时,如果不及时刷新listview,就会抛出上述异常。于是我去掉线程,直接在ui线程中更新数据,发现问题依然存在。

仔细查看代码,我的代码是这样的:


private void prepareData(Calendar c) {
mTodayList = new ArrayList<SCEvent>();
mFutureList = new ArrayList<SCEvent>();
mList = new ArrayList<SCEvent>();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
ArrayList<SCEvent> list = SmartCalendarDB.getInstance(getActivity())
.getBirthdayLatest2(mCalendar.getTimeInMillis(),
cal.getTimeInMillis() != mCalendar.getTimeInMillis());
if(list != null && list.size() > 0) {
int month = mCalendar.get(Calendar.MONTH) + 1;
int day = mCalendar.get(Calendar.DAY_OF_MONTH);
for(SCEvent e : list) {
if(e.getmBirthdayMonth() == month && e.getmBirthdayDay() == day) {
mTodayList.add(e);
} else {
mFutureList.add(e);
}
}
if(mTodayList != null && mTodayList.size() > 0) {
Collections.sort(mTodayList, new TimeComparator());
for(SCEvent e : mTodayList) {
mList.add(e);
}
mList.add(null);
}
if(mFutureList != null && mFutureList.size() > 0) {
if(mTodayList == null || mTodayList.size() <= 0) {
mList.add(null);
}
Collections.sort(mFutureList, new AdvanceComparator());
boolean add = mList != null && mList.size() > 0;
for(SCEvent e : mFutureList) {
mList.add(e);
}
if(!add) {
mList.add(null);
}
}
}
if(mList != null && mList.size() > 0) {
mListView.setVisibility(View.VISIBLE);
mEmptyLayout.setVisibility(View.GONE);
mAdapter.notifyDataSetChanged();
} else {
mListView.setVisibility(View.GONE);
mEmptyLayout.setVisibility(View.VISIBLE);
}
}

我的adapter数据是保存在mlist中,而在代码中不断的改变了mlist内部的数据,而只在最后调用了一次mAdapter.notifyDataSetChanged(),导致listview没有及时刷新而抛出异常。

所以结论在使用listview时,及时不在非ui线程中更新adapter数据,也最好将数据直接定义在adapter类内部或在改变数据时要及时刷新listview,否则会抛出上述异常。

android
修改listview中adapter数据时抛出异常java.lang.IllegalStateException: The content of the
adapter has changed but ListView did not receive a notification问题

时间: 2024-10-10 10:12:02

android 修改listview中adapter数据时抛出异常java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification问题的相关文章

【转】解决java.lang.IllegalStateException: The content of the adapter has changed but ListView...的问题

原文网址:http://blog.csdn.net/ueryueryuery/article/details/20607845 我写了一个Dialog,Dialog中有一个ListView,想要点ListView中的一项后,跳转到另外一个Activity去. 但在使用时,会偶尔报出下面的错误: 02-21 14:54:28.928: E/AndroidRuntime(2846): FATAL EXCEPTION: main 02-21 14:54:28.928: E/AndroidRuntime

Android开发中使用数据库时出现java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.

最近在开发一个 App 的时候用到了数据库,可是在使用数据库的时候就出现了一些问题,在我查询表中的一些信息时出现了一下问题: Caused by: java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed. at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification

ListView UI重绘时触发layoutChildren, 此时会校验listView的mItemCount与其Adapter.getCount是否相同,不同报错. ListView.layoutChildren: mItemCount是在父类AdapterView中定义的,package类型 在两个地方mItemCount会被赋值,初始设置Adapter时: xxAdapter.notifyDataSetChanged时: 因此一定要确保修改adapter数据和notifyDataSetC

Tomcat部署项目时出错java.lang.IllegalStateException: ContainerBase.addChild: start:org.apache.catalina.Life

Tomcat部署项目时出错java.lang.IllegalStateException: ContainerBase.addChild: start:org.apache.catalina.LifecycleException: Failed to start component[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/项目名]] 一个很简单的项目,没有出现编译错误,从Eclipse中用Tomcat v

Android Studio 类库中配置Jpush 报错 java.lang.UnsatisfiedLinkError解决方案

JPush基类库导入需在基类库(注意是基类库,非应用项目)的build.gradle文件-sourceSets项中手动配置jniLibs.srcDir 'src/main/libs',否则JPush无法正确的加载libjpush.so文件 如: sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['

Android开发:java.lang.IllegalStateException报错

常见于ListView列表刷新数据时,更改UI. LOG: 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. DDMS中的log无法定位到准确的出错位置.检查错误可

常见错误之java.lang.IllegalStateException: The application’s PagerAdapter changed the adapter’s cont。。。

如果在logcat日志中出现以下错误: java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 0, found: 4 Pager id: com.activity_test.logo:id/viewpag

SQL Server 2005中的分区表(二):如何添加、查询、修改分区表中的数据

在创建完分区表后,可以向分区表中直接插入数据,而不用去管它这些数据放在哪个物理上的数据表中.接上篇文章,我们在创建好的分区表中插入几条数据: 从以上代码中可以看出,我们一共在数据表中插入了13条数据,其中第1至3条数据是插入到第1个物理分区表中的:第4.5条数据是插入到第2个物理分区表中的:第6至8条数据是插入到第3个物理分区表中的:第9至11条数据是插入到第4个物理分区表中的:第12.13条数据是插入到第5个物理分区表中的. 从SQL语句中可以看出,在向分区表中插入数据方法和在普遍表中插入数据

改变listview中item选中时文字的颜色

当listview的某个item选中时,默认有个选中的高亮显示,如果你要自定义选中时的高亮显示效果,可以在listview中设置属性 1 android:listSelector="@drawable/item_selector" 其中item_selector是在drawable目录下定义的一个xml文件,这种用于突出不同状态下显示效果的xml文件我们称之为selector: 1 2 3 4 5 6 7 <?xml version="1.0" encodin