ListView 异步更新出现问题的解决(Handler)

简介:       忙了一天,终于把问题给解决了,描述一下过程。要完成的功能是Activity中有一个ListView(itemsListView),通过开启一个线程来读取数据库中的联系人列表,ListView通过自定义的BaseAdapter进行关联, 出现的问题代码如下:     ...
 

    忙了一天,终于把问题给解决了,描述一下过程。要完成的功能是Activity中有一个ListView(itemsListView),通过开启一个线程来读取数据库中的联系人列表,ListView通过自定义的BaseAdapter进行关联,

出现的问题代码如下:

       List<String> nameList;         //用于存放联系人的数据源

        itemsListView.setAdapter(new MyListAdapter()):

private class MyListAdapter extends BaseAdapter
    {
        Context context;
        MyListAdapter()
        {
            //this.context = context;
        }
        
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            int i = 0;
            try{
                i = nameList.size();
            }catch(Exception e)
            {
                 Log.e("ERROR", "ERROR IN CODE: " + e.toString());  
                 return i;
            }
            return i;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
              TextView mTextView = new TextView(getApplicationContext());  
              mTextView.setTextSize(18);
              mTextView.setHeight(20);
              mTextView.setBackgroundColor(Color.GRAY);
            try{
        
                  if(nameList.get(position) != null)
                  {
                      mTextView.setText(nameList.get(position));  
                      mTextView.setTextColor(Color.YELLOW);  
                  }
              
           
            }catch(Exception e)
            {
                 Log.e("ERROR", "ERROR IN CODE: " + e.toString());  
            }
             return mTextView;  
    
        }

}

当然,代码中的一些try块是用于调试,不必理会。声明了一个

         Handler mHandler = new Handler(){

          public void handleMessage(Message msg)

         {

                  if(msg.what == REFLESH_LIST)   //REFLESH_LIST 是Activity中定义的int常量

                   {

                       mAdapter.notifyDataSetChanged();

                         itemsListView.setAdapter(mAdapter);

                   }

           }

}


           Thread mThread = new Thread()

{

           public void run()

        {

                 String tmp = DataBaseread();            //这里DataBaseRead是读取数据库中的一个联系人,返回该联系人的name

                  nameList.add(tmp);

                  mHandler.sendEmptyMessage(REFLESH_LIST);

       }

}

        编译、第一次运行没有问题,但是当我按Back键后,再次进入后发现了严重问题,出现了ListView内部layoutChildren函数的问题,查了一天的资料,那个痛苦哦,很多解决方案都不管用

有的说在  notifyDataSetChanged方法前面加入itemsListView.setVisibility(View.GONE),在其后加入itemsListView.setVisibility(View.Visible)

有的利用ListView 的requestLayout方法替代notifyDataSetChanged,以及换成AsyncTask来做,很多都还是老外们的方法,但都不能解决我的问题,后来怀疑是同步问题,因为线程不停添加nameList中的而数据,并发送Msg给Handler,而有可能会出现Msg队列堆积起来,来不及处理的情况,这样的话nameList的实际数据与mAdapter中提供给ListView的数据不一致,所以尝试了下面的方法,将nameList添加元素和notififyDataChanged函数放到了一起执行,测试了一下,竟然真是这样的原因,豁然开朗哇,呵呵,更改如下:


           Thread mThread = new Thread()

{

           public void run()

        {

                 String tmp = DataBaseread();            //这里DataBaseRead是读取数据库中的一个联系人,返回该联系人的name

                     Message msg = new Message();
                            msg.obj = new String(tmp);
                            msg.what = REFRESH_LIST;
                    
                                mHandler.sendMessage(msg);

              }

}
                        
private Handler mHandler = new Handler()
    {
            public void handleMessage(Message msg) {
                 
                                     nameList.add((String)msg.obj);
                                   mAdapter.notifyDataSetChanged();
                                    itemsListView.setVisibility(View.VISIBLE);
                              
                    super.handleMessage(msg);
            }
           
    };

      希望对大家有帮助!!!!!!!!!!! 

相关文章
|
7月前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
371 0
|
Android开发
【Android 异步操作】Handler 机制 ( Handler 常用用法 | HandlerThread 简介 | HandlerThread 源码注释分析 )
【Android 异步操作】Handler 机制 ( Handler 常用用法 | HandlerThread 简介 | HandlerThread 源码注释分析 )
135 0
|
消息中间件 存储 Android开发
【Android 异步操作】Handler 机制 ( Android 提供的 Handler 源码解析 | Handler 构造与消息分发 | MessageQueue 消息队列相关方法 )
【Android 异步操作】Handler 机制 ( Android 提供的 Handler 源码解析 | Handler 构造与消息分发 | MessageQueue 消息队列相关方法 )
151 0
|
消息中间件 Android开发
【Android 异步操作】手写 Handler ( Handler 发送与处理消息 | Handler 初始化 | 完整 Handler 代码 )
【Android 异步操作】手写 Handler ( Handler 发送与处理消息 | Handler 初始化 | 完整 Handler 代码 )
151 0
|
消息中间件 Java Linux
【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )
【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )
155 0
C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
原文:C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较 使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新   使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和不夸跨线程执行UI更新报错的最佳实践,附加几种其他方式比较 由于是Winform代码和其他原因,本文章只做代码截图演示,不做界面UI展示,当然所有代码都会在截图展示。
4895 0