bekitty

我不会讲大道理,可我心里有一杆秤。 我看这个世界很苛刻,可我的心里很宽容。 我不需要权力与利益,可是我需要公平与正义。 我始终知道正道难行,可不得不行。

导航

Android通讯录加载大数据的优化问题

Posted on 2013-10-09 11:49  bekitty  阅读(2062)  评论(0编辑  收藏  举报

在最近的开发中,遇到一个问题,在自己开发的通讯录中,500条联系人加载时慢的问题。 
最初把同步本地通讯录的操作,放在软件的loading页去做,把联系人读到缓存中,发现当数据大时,loading页会进入得很慢。然后试着用CursorAdapter去做,实现列表滚动去读数据库,但又发现当用户平凡刷列表时,会出现内存溢出的情况。 

那怎么办呢,于是我综合两种情况的优点,进行了合并。当用户在滑动列表时,会把列表显示的部分通过读数据。读出来的数据放入一个MAP中,那么当用户下一次滑到之前的位置时,只需要从MAP中读取数据了。这样即解决了数据量大量,加载到缓存慢,又解决了滑动列表卡的问题。下面是代码 

1.首先通过android 通讯录数据库提供的索引表ContactsContract.RawContacts.CONTENT_URI把所有的联系人ID查询出来。  

 private List<Long> loadAllContactIds(){
        List<Long> arr = new ArrayList<Long>();
        Cursor cursor = cr.query(ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.DELETED + " = 0",null,null);
        if(null != cursor && cursor.moveToFirst()){
            do{
                long id = cursor.getLong(cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID));
                arr.add(id);
            }while(cursor.moveToNext());
            cursor.close();
        }
        return arr;
    }

 

2.再通过ID把联系人的各种信息读出来。

private String loadAllContactInfo(long id){
        Cursor cursor = cr.query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.RAW_CONTACT_ID + " = "+id,null,null);
        StringBuffer sb = new StringBuffer();
        if(null != cursor && cursor.moveToFirst()){
            do{
                String type = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
                if(type.equals(StructuredName.CONTENT_ITEM_TYPE)){
                    sb.append(cursor.getString(cursor.getColumnIndex(StructuredName.DISPLAY_NAME))).append("|");
                }else if(type.equals(Nickname.CONTENT_ITEM_TYPE)){
                    sb.append(cursor.getString(cursor.getColumnIndex(Nickname.NAME))).append("|");
                }else if(type.equals(Phone.CONTENT_ITEM_TYPE)){
                    sb.append(cursor.getString(cursor.getColumnIndex(Phone.NUMBER))).append("|");
                }else if(type.equals(Event.CONTENT_ITEM_TYPE) && Event.TYPE.equals(Event.TYPE_BIRTHDAY)){
                    sb.append(cursor.getString(cursor.getColumnIndex(Event.DATA1))).append("|");
                }
            }while(cursor.moveToNext());
            cursor.close();
        }
        return sb.toString();
    }   

 

3.自定义的adapter ,

 private class MyAdapter extends BaseAdapter{
        
        private List<Long> ids;
        private Map<Long,String> maps;  
        
        public MyAdapter(List<Long> ids){
            this.ids = ids;
            maps = new HashMap<Long, String>();
        }

    @Override
    public int getCount() {
       return this.ids.size();
    }

    @Override
    public Object getItem(int position) {
       return this.ids.get(position);
    }

    @Override
    public long getItemId(int position) {
       return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
               if(null == convertView){
        convertView = LayoutInflater.from(TextTextActivity.this).inflate(android.R.layout.simple_list_item_1, null);
        }
        long id = ids.get(position);
        if(convertView instanceof TextView){
                     String res = maps.get(id);
            TextView tv = (TextView)convertView;
            if(TextUtils.isEmpty(res)){
                res = loadAllContactInfo(id);
                maps.put(id, res);
            }
            tv.setText(res);
        }
        return convertView;
    }
    }