Cursor phoneCursor = this.managedQuery( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
再根据号码来查联系人
if(0 < phoneCursor.getCount()){ phoneCursor.moveToFirst(); // find all contact list while (phoneCursor.getPosition() != phoneCursor.getCount()) { ContactEntity contactentity = new ContactEntity(); contactentity.contact_id = phoneCursor .getLong(phoneCursor .getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); contactentity.contacts_phone_type = phoneCursor .getInt(phoneCursor .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); contactentity.contacts_phone_number = phoneCursor .getString(phoneCursor .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace( "-", ""); contactCursor = this.managedQuery( ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts._ID + "=" + contactentity.contact_id, null, null); contactCursor.moveToFirst(); contactentity.contacts_display_name = contactCursor .getString(contactCursor .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)).replace( "-", ""); Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactentity.contact_id); InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), uri); if(null != input){ contactentity.contact_phone_bmp = BitmapFactory.decodeStream(input); } // spell name can contactentity.spellName = PinYin.getInstance(this).getPinyinString( contactentity.contacts_display_name); Log.i(TAG, "contactentity.contact_id: " + contactentity.contact_id + " contactentity.contacts_phone_type: " + contactentity.contacts_phone_type + " contactentity.contacts_phone_number: " + contactentity.contacts_phone_number + "contactentity.contacts_display_name: " + contactentity.contacts_display_name + "contactentity.contact_phone_bmp: " + contactentity.contact_phone_bmp); phoneCursor.moveToNext(); customArrayList.add(contactentity); }
经过测试发现性能消耗主要在这个while循环当中!因为在循环当中在加一个查询数据库操作自然慢!
解决方案:
发现在查询ContactsContract.CommonDataKinds.Phone.CONTENT_URI数据库时其实可以吧
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID查询出来
那么把原来的
private final static String[] mContactsProjection = new String[] { ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.NUMBER, };
改为
private final static String[] mContactsProjection = new String[] { ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.PHOTO_ID };
下面对应改为
while (phoneCursor.getPosition() != phoneCursor.getCount()) { ContactEntity contactentity = new ContactEntity(); contactentity.contacts_id = phoneCursor.getLong(0); contactentity.contacts_phone_type = phoneCursor.getInt(1); contactentity.contacts_phone_number = phoneCursor.getString(2) .replace("-", ""); contactentity.contacts_display_name = phoneCursor.getString(3).replace("-", ""); contactentity.contacts_photo_id = phoneCursor.getString(4); // spell name can contactentity.spellName = PinYin.getInstance(this) .getPinyinString(contactentity.contacts_display_name); // Log.i(TAG, "contactentity.contact_id: " + // contactentity.contact_id // + " contactentity.contacts_phone_type: " // + contactentity.contacts_phone_type // + " contactentity.contacts_phone_number: " // + contactentity.contacts_phone_number // + "contactentity.contacts_display_name: " // + contactentity.contacts_display_name // + "contactentity.contact_phone_bmp: " // + contactentity.contact_phone_bmp); phoneCursor.moveToNext(); customArrayList.add(contactentity); } }
这样改变后只读一次数据库!
在1000联系人的情况下耗时打LOG得到不到2000毫秒!
其他优化方向!
1、查询数据库时把managedquerey第二参数projection写时!只查需要的列!不查询全部!
2、在contactentity.contact_id = phoneCursor
.getLong(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));取值时直接用数组序号0,1,2代替!
3.图片等大数据量数据可放在getview方法中直接赋值而不通过对象传递!