Android 号码查询性能优化

我的需求是做一个快速拨号界面!list列表显示所有联系人Calllog资料!原来的做法在前面的日志中有提到!大概是先查
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方法中直接赋值而不通过对象传递!
上一篇:前端性能优化点(笔记)


下一篇:高性能网络I/O框架-netmap源码分析(1)