Android通讯录开发之解决快速搜索联系人线程同步问题

转载自小巫的博客: http://blog.csdn.net/wwj_748/article/details/18216721


上一篇博客介绍的是如何实现搜索,在PhoneUtil中已经定义好了search方法,开发者直接拿来用就ok了,但用的时候肯定会遇到线程同步问题,如何解决搜索的时候UI线程卡顿的现象,这时候就需要另开一个线程来进行搜索操作了,但由于在搜索框输入字符的时候,一般都是快速输入的,这就会导致线程同步问题的出现,搜索出来的结果会不对。小巫由于经验不足还有相关知识的欠缺,在遇到这个问题的时候一直没能解决,所以只能去请教有经验的工程师了,最终也找到解决办法。

   在UI线程我们知道超过5秒的操作就会出现卡顿或者ANR对话框,所以一般费时的操作绝不能放在UI线程,但数据的更新和通知就要放在UI线程来实现了,比如ListView的adapter的数据更新就要在UI线程里通知,不然就可能出现数据没有得到即使更新的现象。

   这些问题只有在实际开发当中才会遇到,我废话也不多说了,下面是解决方案。

   搜索框,文本变化的监听

  

[java]  view plain copy
  1. searchEditText.addTextChangedListener(new TextWatcher() {  
  2.   
  3.             @Override  
  4.             public void onTextChanged(final CharSequence s, int start,  
  5.                     int before, int count) {  
  6.                 if (!TextUtils.isEmpty(s)) {  
  7.                     btnClear.setVisibility(View.VISIBLE);  
  8.                     selectAllBtn.setVisibility(View.GONE);  
  9.                     searchList(s.toString());  
  10.                 } else {// 如果输入框内容为空,显示全部  
  11.                     btnClear.setVisibility(View.GONE);  
  12.                     selectAllBtn.setVisibility(View.VISIBLE);  
  13.                     searchList("");  
  14.                 }  
  15.             }  
  16.   
  17.             @Override  
  18.             public void beforeTextChanged(CharSequence s, int start, int count,  
  19.                     int after) {  
  20.             }  
  21.   
  22.             @Override  
  23.             public void afterTextChanged(final Editable s) {  
  24.   
  25.             }  
  26.   
  27.         });  

一般搜索框会有删除的×,我这里还有控制显示全选的框,效果如下:

Android通讯录开发之解决快速搜索联系人线程同步问题_第1张图片Android通讯录开发之解决快速搜索联系人线程同步问题_第2张图片


在文本变化的时候会不断刷新列表,会调用searchList的方法,通过传递字符串来实现更新列表

通过lastest这个标识来解决线程同步问题,只有i跟lastest相等的时候采取刷新列表,其实这个办法并不土,不知道网友是否有更好的实现方法,麻烦指教一下。

[java]  view plain copy
  1. private static int lastest = 0;  
  2.   
  3. // 实现线程同步搜索联系人  
  4. // 线程同步问题可能会导致数据显示错误,比如会显示上一次搜索到的数据  
  5. public void searchList(final String s) {  
  6.     // 用户可能正在快速输入电话号码,之前在搜索的联系人列表已经过时了。  
  7.     final int i = ++lastest;  
  8.     // 开一个线程来进行快速搜索  
  9.     new Thread(new Runnable() {  
  10.   
  11.         @Override  
  12.         public void run() {  
  13.             if (TextUtils.isEmpty(s)) {  
  14.                 // 如果输入的字符串为空,则显示所有联系人  
  15.                 searchContacts = allContacts;  
  16.             } else {  
  17.                 // searhContacts指向搜索返回的list  
  18.                 searchContacts = PhoneUtil.search(s, allContacts);  
  19.             }  
  20.   
  21.             if (i == lastest) { // 避免线程同步问题  
  22.                 LocalContactActivity.this.runOnUiThread(new Runnable() {  
  23.   
  24.                     @Override  
  25.                     public void run() {  
  26.                         if (i == lastest) { // 避免线程同步问题  
  27.                             contactList.clear();  
  28.                             contactList.addAll(searchContacts);  
  29.                             refreshList();  
  30.                         }  
  31.                     }  
  32.                 });  
  33.             }  
  34.         }  
  35.     }).start();  
  36. }  

数据有更新,调用adapter的notifyDataSetChanged()方法就可以达到刷新列表效果。


[java]  view plain copy
  1. /** 刷新列表和确认按钮 **/  
  2. public void refreshList() {  
  3.     // adapter.setContactList(contactList);  
  4.     adapter.notifyDataSetChanged();  
  5.     refreshBtnOK();  
  6.   
  7. }  

你可能感兴趣的:(android,通讯录)