• 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);
                }
               
        };

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

  • 相关阅读:
    编程实现Windows系统自动登录
    IOS开发笔记
    所有的GUI Toolkit,类型之多真开眼界
    文件保护DEP
    Delphi 重启应用程序(创建Bat文件的Process)
    Linux的几个概念,常用命令学习
    Delphi内存操作API函数(备查,并一一学习)
    Servle中的会话管理
    Windows软件在Linux上的等价/替代/模仿软件列表 (抄一个)
    Go 的文件系统抽象 Afero
  • 原文地址:https://www.cnblogs.com/new0801/p/6175904.html
Copyright © 2020-2023  润新知