文档章节

The content of the adapter has changed but ...

iSnowFlake
 iSnowFlake
发布于 2015/12/14 16:59
字数 1402
阅读 521
收藏 0

今天看官方的下拉刷新的时候,改了一下Demo ,发现一直在奔溃

import java.util.ArrayList;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public class PushMessageActivity extends Activity {
    private SwipeRefreshLayout swipeRefreshLayout;
    private ArrayList<String> data = new ArrayList<String>();
    private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pushmess_layout);

        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
        ListView listView = (ListView) findViewById(R.id.listView);

        // 设置刷新动画的颜色,可以设置1或者更多.
        // 我们暂时使用三个Android系统自带的颜色。
        swipeRefreshLayout.setColorSchemeResources(
                android.R.color.holo_blue_bright,
                android.R.color.holo_orange_light,
                android.R.color.holo_green_light
                ,android.R.color.holo_red_light);

        swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener() {

            // SwipeRefreshLayout接管其包裹的ListView下拉事件。
            // 每一次对ListView的下拉动作,将触发SwipeRefreshLayout的onRefresh()。
            @Override
            public void onRefresh() {
                longTimeOperation();
            }
        });

        // 使用Android系统自带的一个简单TextView布局文件android.R.layout.simple_list_item_1显示我们的数据内容。
        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);
    }

    // 每一次下拉刷新将触发更新操作动作。
    // 这里将是比较耗时的操作:如网络请求的数据,加载一个大图片。
    // 简单期间,我们假设就是简单的将count数据加1,然后更新显示。
    //
    // 备注:swipeRefreshLayout.setRefreshing(true) 到
    // swipeRefreshLayout.setRefreshing(false)之间的这段代码 ,
    // 在实际的应用开发中一般就是线程化的、耗时的或者后台的操作代码。
    private void longTimeOperation() {
        // true,刷新开始,所以启动刷新的UI样式.
        swipeRefreshLayout.setRefreshing(true);
        data.add(0, "添加新的item:" + new Random().nextInt());
//        adapter.notifyDataSetChanged();

        // 开始启动刷新...
        // 在这儿放耗时操作的 AsyncTask线程、后台Service等代码。

        // add(0,xxx)每次将更新的数据xxx添加到头部。
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
//                data.add(0, "添加新的item:" + new Random().nextInt());
                
//                adapter.notifyDataSetChanged();

                //停止刷新动画
                swipeRefreshLayout.setRefreshing(false);

            }
        }, 2000);

    }

}


   发现如果你在下拉的过程中点击的话经常的奔溃,不点击没有关系。错误的Log如下所示!


12-14 16:32:11.705: E/InputEventReceiver(18719): Exception dispatching input event.
12-14 16:32:11.705: E/MessageQueue-JNI(18719): Exception in MessageQueue callback: handleReceiveCallback
12-14 16:32:11.707: E/MessageQueue-JNI(18719): 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. 
Make sure your adapter calls notifyDataSetChanged() when its content changes. 
[in ListView(2131230721, class android.widget.ListView) with Adapter(class android.widget.ArrayAdapter)]

12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.widget.ListView.layoutChildren(ListView.java:1562)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.widget.AbsListView.onTouchUp(AbsListView.java:3838)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:3637)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.View.dispatchTouchEvent(View.java:8471)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.View.dispatchPointerEvent(View.java:8666)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.os.MessageQueue.nativePollOnce(Native Method)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.os.MessageQueue.next(MessageQueue.java:143)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.os.Looper.loop(Looper.java:122)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at android.app.ActivityThread.main(ActivityThread.java:5254)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at java.lang.reflect.Method.invoke(Native Method)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at java.lang.reflect.Method.invoke(Method.java:372)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
12-14 16:32:11.707: E/MessageQueue-JNI(18719):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)


   其实实际的业务中,数据的改变是不会那么做的,但是还是要找找为什么?!上面的错误翻译成中文就是:

Adapter的数据内容已经改变,但是ListView却未接收到通知。要确保不在后台线程中修改Adapter的数据内容,而要在UI Thread中修改。确保Adapter的数据内容改变时一定要调用notifyDataSetChanged()方法。

当ListView缓存的数据Count和ListView中Adapter.getCount()不等时,并且在这个时候ListView 发生了交互事件就会会抛出该异常。

看看List 的源码   

@Override
protected void layoutChildren() { 中的代码:


               data.add(0, "添加新的item:" + new Random().nextInt());     
               adapter.notifyDataSetChanged();

 

其实这两行行代码放在一块就好了,并且你要保证notifyDataSetChangd() 是在主线程中进行的!

其实这两行行代码放在一块就好了,并且你要保证notifyDataSetChangd() 是在主线程中进行的!

其实这两行行代码放在一块就好了,并且你要保证notifyDataSetChangd() 是在主线程中进行的!

© 著作权归作者所有

iSnowFlake
粉丝 34
博文 93
码字总数 53328
作品 0
深圳
高级程序员
私信 提问
listView adapter 的java.lang.IllegalStateException

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......

Jonson
2016/05/16
23
0
《每日一剂》适配器刷新报错adapter.notifyDataSetChanged()解决

在使用ListView过程中,有时会出现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 ......

王先森oO
2018/05/29
0
0
解决listview出现线程更新错误问题

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......

MrLovelyCbb
2011/12/09
0
1
关于ListView中的一个问题

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......

黑菜妞妞
2011/07/22
787
5
如何有效的排查和解决 ListView的java.lang.IllegalStateException的问题

如题,目前开发的软件在每天的crash日志中经常有3到4例这种crash,并且有经验的都知道这个crash从日志是无法精确定位的,只是提示 “The content of the adapter has changed but ListView d...

PepsiZero
2012/06/01
331
1

没有更多内容

加载失败,请刷新页面

加载更多

centos7 新手阿里云服务器安装mongodb

简介 MongoDB 是一个基于分布式 文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案 MongoDB特点 模式自由 :可以把不同结构的文档存...

醉雨
16分钟前
1
0
sql注入漏洞,应屏蔽SQL注入攻击

注:SQL注入好比是前端URL传参数请求时参数以SQL 做为参数传入,如 select 1 from dual where 1=1 or 1=1 and 1=2;(类似这样的SQL语句) 防御方法 如果自己编写防注代码,一般是先定义一个函...

颜丽
16分钟前
1
0
装饰者模式

 代理模式与装饰者模式看起来很像,都实现基础对象实现的接口,在其自身对象中都保存着对被代理/被装饰者的对象引用。   先来看看装饰者模式的定义:动态的将责任附加到被装饰者对象上,用...

铁骨铮铮
21分钟前
0
0
我为什么飞行 10000 公里去西班牙参加 KubeCon?

2019 年 5 月 20 日至 23 日, 由 Cloud Native Computing Foundation (CNCF) 主办的云原生技术大会 KubeCon + CloudNativeCon EU(欧洲场)即将在热情洋溢的巴塞罗那盛装启幕。 作为云计算领...

zhaowei121
39分钟前
0
0
Node.getTextContent() not found 解决办法【不需要调整builder path下面包顺序】

新导入的工程,w3c的getTextContent找不到,response的setCharacterEncoding找不到,网上很多教程都是“调整工程builder path的lib包顺序把jre、tomcat调到上面即可”,但是进入项目的build...

嘿嘿嘿IT
46分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部