Android 号码查询性能优化

来源:互联网 发布:压切长谷部数据 编辑:程序博客网 时间:2024/04/30 13:42
我的需求是做一个快速拨号界面!list列表显示所有联系人Calllog资料!原来的做法在前面的日志中有提到!大概是先查
Java代码 复制代码 收藏代码
  1. Cursor phoneCursor = this.managedQuery(
  2. ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,
  3. null, null);

再根据号码来查联系人
Java代码 复制代码 收藏代码
  1. if(0 < phoneCursor.getCount()){
  2. phoneCursor.moveToFirst();
  3. // find all contact list
  4. while (phoneCursor.getPosition() != phoneCursor.getCount()) {
  5. ContactEntity contactentity = new ContactEntity();
  6. contactentity.contact_id = phoneCursor
  7. .getLong(phoneCursor
  8. .getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
  9. contactentity.contacts_phone_type = phoneCursor
  10. .getInt(phoneCursor
  11. .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
  12. contactentity.contacts_phone_number = phoneCursor
  13. .getString(phoneCursor
  14. .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(
  15. "-", "");
  16. contactCursor = this.managedQuery(
  17. ContactsContract.Contacts.CONTENT_URI, null,
  18. ContactsContract.Contacts._ID + "="
  19. + contactentity.contact_id, null, null);
  20. contactCursor.moveToFirst();
  21. contactentity.contacts_display_name = contactCursor
  22. .getString(contactCursor
  23. .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)).replace(
  24. "-", "");
  25. Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,
  26. contactentity.contact_id);
  27. InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), uri);
  28. if(null != input){
  29. contactentity.contact_phone_bmp = BitmapFactory.decodeStream(input);
  30. }
  31. // spell name can
  32. contactentity.spellName = PinYin.getInstance(this).getPinyinString(
  33. contactentity.contacts_display_name);
  34. Log.i(TAG, "contactentity.contact_id: " + contactentity.contact_id
  35. + " contactentity.contacts_phone_type: "
  36. + contactentity.contacts_phone_type
  37. + " contactentity.contacts_phone_number: "
  38. + contactentity.contacts_phone_number
  39. + "contactentity.contacts_display_name: "
  40. + contactentity.contacts_display_name
  41. + "contactentity.contact_phone_bmp: "
  42. + contactentity.contact_phone_bmp);
  43. phoneCursor.moveToNext();
  44. customArrayList.add(contactentity);
  45. }


经过测试发现性能消耗主要在这个while循环当中!因为在循环当中在加一个查询数据库操作自然慢!

解决方案:
发现在查询ContactsContract.CommonDataKinds.Phone.CONTENT_URI数据库时其实可以吧
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID查询出来
那么把原来的

Java代码 复制代码 收藏代码
  1. private final static String[] mContactsProjection = new String[] {
  2. ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
  3. ContactsContract.CommonDataKinds.Phone.TYPE,
  4. ContactsContract.CommonDataKinds.Phone.NUMBER,
  5. };

改为
Java代码 复制代码 收藏代码
  1. private final static String[] mContactsProjection = new String[] {
  2. ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
  3. ContactsContract.CommonDataKinds.Phone.TYPE,
  4. ContactsContract.CommonDataKinds.Phone.NUMBER,
  5. ContactsContract.Contacts.DISPLAY_NAME,
  6. ContactsContract.Contacts.PHOTO_ID
  7. };


下面对应改为
Java代码 复制代码 收藏代码
  1. while (phoneCursor.getPosition() != phoneCursor.getCount()) {
  2. ContactEntity contactentity = new ContactEntity();
  3. contactentity.contacts_id = phoneCursor.getLong(0);
  4. contactentity.contacts_phone_type = phoneCursor.getInt(1);
  5. contactentity.contacts_phone_number = phoneCursor.getString(2)
  6. .replace("-", "");
  7. contactentity.contacts_display_name = phoneCursor.getString(3).replace("-","");
  8. contactentity.contacts_photo_id = phoneCursor.getString(4);
  9. // spell name can
  10. contactentity.spellName = PinYin.getInstance(this)
  11. .getPinyinString(contactentity.contacts_display_name);
  12. // Log.i(TAG, "contactentity.contact_id: " +
  13. // contactentity.contact_id
  14. // + " contactentity.contacts_phone_type: "
  15. // + contactentity.contacts_phone_type
  16. // + " contactentity.contacts_phone_number: "
  17. // + contactentity.contacts_phone_number
  18. // + "contactentity.contacts_display_name: "
  19. // + contactentity.contacts_display_name
  20. // + "contactentity.contact_phone_bmp: "
  21. // + contactentity.contact_phone_bmp);
  22. phoneCursor.moveToNext();
  23. customArrayList.add(contactentity);
  24. }
  25. }

这样改变后只读一次数据库!
在1000联系人的情况下耗时打LOG得到不到2000毫秒!
其他优化方向!
1、查询数据库时把managedquerey第二参数projection写时!只查需要的列!不查询全部!
2、在contactentity.contact_id = phoneCursor
.getLong(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));取值时直接用数组序号0,1,2代替!
3.图片等大数据量数据可放在getview方法中直接赋值而不通过对象传递!