android PullToRefreshListView报错
    我在项目中导入了PullToRefreshListView这个包,然后实现了上拉刷新和下拉刷新的

接口,我在模拟器中调试程序,发现下拉刷新刷几次就崩了,报错: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(16908298, class com.handmark.pulltorefresh.library.PullToRefreshListView$InternalListViewSDK9) with Adapter
网上说更新adpater要在UI线程里面进行。我是在UI线程里面进行的。我的整体思路是这样的:下拉刷新之后,在异步任务中下载数据,下载完成后用handler来告知主线程,在主线程中mAdapter.notifyDataSetChanged();然后pullToRefreshListView.onRefreshComplete();
感觉没什么问题啊,而且我还加了判断,当下拉刷新正在执行的话就直接onRefreshComplete但是在模拟器上面,滑动几次就报上面的错误了。然后我又在真机上面测试,滑了很多次又没有报错,难道是模拟器的原因吗?如果是模拟器的原因的那还好,万一不是的,但是真机上现在现在不报错,到时候上线了报错怎么办?求大神告知解决办法

我的代码:
public class ClubMemberActivity extends Activity {
private TopBar topBar;//顶部导航栏
private Listlist = new ArrayList<>();//数据集合
private TextView textView;//刚进入页面时提示用户正在加载数据
private PullToRefreshListView pullToRefreshListView;
private ClubMemberAdapter clubMemberAdapter;//Adapter
private boolean isRefresh = false;//判断是否正在执行刷新

Handler handler = new Handler(){
    /**
     * Subclasses must implement this to receive messages.
     *
     * @param msg
     */
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what){

            case 0:
                //更新pullToRefreshListview
                clubMemberAdapter.list = list;
                clubMemberAdapter.notifyDataSetChanged();
                pullToRefreshListView.onRefreshComplete();
                isRefresh = false;
                break;
            case 1:
                textView.setVisibility(View.GONE);//数据加载完成后,设置此View为GONE
                clubMemberAdapter = new ClubMemberAdapter(list, ClubMemberActivity.this,false);
                pullToRefreshListView = (PullToRefreshListView) findViewById(R.id.id_lv_clubMM);
                pullToRefreshListView.setAdapter(clubMemberAdapter);
                pullToRefreshListView.setMode(PullToRefreshBase.Mode.BOTH);
                pullToRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
                    @Override
                    public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
                        if (!isRefresh){
                            isRefresh = true;
                            new getDataTask().execute(1);
                        }else{
                            pullToRefreshListView.onRefreshComplete();
                        }

                    }

                    @Override
                    public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
                        if (!isRefresh){
                            isRefresh = true;
                            new getDataTask().execute(0);
                        }else{
                            pullToRefreshListView.onRefreshComplete();
                        }
                    }

                });
                break;
        }
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_clubmember);
    initView();
}

//初始化一些控件
private void initView() {
    topBar = (TopBar) findViewById(R.id.id_topBar_clubMM);
    topBar.setOnTopBarClickListener(new TopBar.TopBarClickListener() {
        @Override
        public void OnClick_left() {
            finish();
        }

        @Override
        public void OnClick_center() {

        }

        @Override
        public void OnClick_right() {

        }
    });
    textView = (TextView) findViewById(R.id.id_txt_clubMM_loading);
    getData();
}

/**
 * 字符串转换为图片(模拟下载图片,所以先将本地的图片转换成字符串,在Adapter中再将字符串转换成图片)
 * @param drawable
 * @return
 */
public  synchronized  String drawableToByte(Drawable drawable) {
    if (drawable != null) {
        Bitmap bitmap = Bitmap
                .createBitmap(
                        drawable.getIntrinsicWidth(),
                        drawable.getIntrinsicHeight(),
                        drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                                : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        int size = bitmap.getWidth() * bitmap.getHeight() * 4;

        // 创建一个字节数组输出流,流的大小为size
        ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
        // 设置位图的压缩格式,质量为100%,并放入字节数组输出流中
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        // 将字节数组输出流转化为字节数组byte[]
        byte[] imagedata = baos.toByteArray();

        String icon= Base64.encodeToString(imagedata, Base64.DEFAULT);
        return icon;
    }
    return null;
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void getData(){
    new Thread(){
        @Override
        public void run() {
            /**
             * 测试用数据
             */
            for (int i = 0; i < 10; i++) {
                ClubMembers clubmm = new ClubMembers();
                clubmm.clubMembID = i + "";
                clubmm.name = "死神" + i;
                clubmm.photo = drawableToByte(getDrawable(R.drawable.head));
                clubmm.playerID = "palyerID" + i;
                clubmm.worth = new Worth();
                clubmm.worth.arena_worth = 100 + "";
                clubmm.worth.arena_Name = "name" + i;
                list.add(clubmm);
            }
            handler.sendEmptyMessage(1);
        }
    }.start();

}

private class getDataTask extends AsyncTask<Integer,Void,Integer>{

    @Override
    protected Integer doInBackground(Integer... params) {
        //模拟下载数据
        Log.e("infoo","开始异步操作");
        if (params[0] == 1){
            for (int i = 0;i<5;i++){
                ClubMembers clubmm = new ClubMembers();
                clubmm.clubMembID = i + "我是添加数据";
                clubmm.name = "死神(我是添加的数据)" + i;
                clubmm.photo = drawableToByte(getDrawable(R.drawable.head));
                clubmm.playerID = "palyerID" + i;
                clubmm.worth = new Worth();
                clubmm.worth.arena_worth = 100 + "";
                clubmm.worth.arena_Name = "name" + i;
                list.add(0,clubmm);
            }
        }else{
            for (int i = 0;i<5;i++){
                ClubMembers clubmm = new ClubMembers();
                clubmm.clubMembID = i + "我是添加数据";
                clubmm.name = "死神(我是添加的数据)" + i;
                clubmm.photo = drawableToByte(getDrawable(R.drawable.head));
                clubmm.playerID = "palyerID" + i;
                clubmm.worth = new Worth();
                clubmm.worth.arena_worth = 100 + "";
                clubmm.worth.arena_Name = "name" + i;
                list.add(list.size(),clubmm);
            }
        }
        Log.e("infoo","size === "+list.size());
        return null;
    }

    @Override
    protected void onPostExecute(Integer s) {
        super.onPostExecute(s);
        handler.sendEmptyMessage(0);
    }
}

}

3个回答

我已经解决了错误,主要是我的adapter.notifyDataSetChanged()这个函数是在子线程中调用的。导致了错误。这个函数执行后View会重绘,这肯定应该是在UI线程中去执行的。所以报错了。

刚刚发现,在真机上也出现了相同的错误。我一直很快的刷新,刷个8、9次后真机也报错了。。。。。。

是不是你的SDK的版本太低,PullToRefresh的最低的SDk的版本要求要大于9,我一般惠选哲SDk的最小版本为11

qq_35071078
下课睡觉 不是啊,我都是用的很新的sdk写的都是20左右的
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问