关于android通讯录加载大数据的优化问题

在最近的开发中,遇到一个问题,在自己开发的通讯录中,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;
	}
    }

相关推荐