zoukankan      html  css  js  c++  java
  • ListView 异步更新出现问题的解决(Handler)

     

        忙了一天,终于把问题给解决了,描述一下过程。要完成的功能是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);
                }
               
        };

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

  • 相关阅读:
    Java对象的生命周期与作用域的讨论(转)
    [置顶] Oracle学习路线与方法
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
  • 原文地址:https://www.cnblogs.com/new0801/p/6175904.html
Copyright © 2011-2022 走看看