在最近的开发中,遇到一个问题,在自己开发的通讯录中,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;
- }
- }
相关推荐
"基于Android+SQLite的手机通讯录管理器" 知识点一:Android平台下的数据库管理 Android平台下,SQLite是最常用的数据库管理系统。SQLite是一种轻量级的 Relation Database Management System(关系数据库管理系统...
对于大数据集,为了避免一次性加载所有数据导致性能问题,可以使用异步加载和数据分页策略。异步加载是在后台线程处理数据,主线程继续处理用户界面,提高用户体验。数据分页则是在用户滚动到列表底部时加载更多数据...
在Android开发中,"android字母排序"是一种常见的功能,它使得用户可以快速浏览和定位大量条目,就像微信通讯录中的字母栏一样。这个功能通常用于应用的联系人列表、商品目录或者其他需要按名称查找的数据集。以下是...
1. **ListView**:ListView是Android系统中用于显示多行数据的视图组件,它可以动态加载和滚动数据,非常适合处理大数据集。SortListViewDemo中,ListView被用来展示联系人列表,每个列表项代表一个联系人。 2. **...
9. **性能优化**:对于大量联系人的操作,可能会涉及到性能优化,如使用合适的数据结构,避免不必要的遍历,以及在操作大数据时考虑使用并发和多线程。 10. **测试与调试**:为了保证功能的正确性,开发者通常会...