Android 号码查询性能优化

我的需求是做一个快速拨号界面!list列表显示所有联系人Calllog资料!原来的做法在前面的日志中有提到!大概是先查

Java代码

  1. Cursor phoneCursor = this.managedQuery(
  2. ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
    null,
  3. null, null);
Cursor phoneCursor = this.managedQuery(
				ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
				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. }
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查询出来
那么把原来的

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. };
private final static String[] mContactsProjection = new String[] {
			ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
			ContactsContract.CommonDataKinds.Phone.TYPE,
			ContactsContract.CommonDataKinds.Phone.NUMBER,

	};

改为

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. };
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
	};

下面对应改为

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. }
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方法中直接赋值而不通过对象传递!  

时间: 2024-11-03 20:56:40

Android 号码查询性能优化的相关文章

Android 界面的性能优化 —— 减少过度绘制

本文讲的是Android 界面的性能优化 -- 减少过度绘制, 你有了一个很棒的灵感,并且把它制作成了一个应用程序发布到了网上.但是,现在你听到了来自用户的抱怨,例如这个应用程序运行起来很慢有卡顿的感觉并且太难使用.. 有一个简单的解决方法是,你可以使用 GPU Overdraw 工具来改进应用程序的渲染时间. 什么是过度绘制? 过度绘制发生在每一次应用程序要求系统在某些界面上再绘制一些界面的时候.这个 Debug GPU Overdraw 工具可以在屏幕最上层叠加上一些颜色,它显示出一个像素点

SQL Server查询性能优化之创建合理的索引(下)

续上一篇SQLServer查询性能优化之创建合理的索引(上) 数据库索引分为聚集索引和非聚集索引,聚集索引就是物理索引,也就是数据的物理的存储顺序,聚集索引的叶子节点就是数据行本身:非聚集索引是逻辑索引,也可以简单的认为是对聚集索引建立的索引,一般来说聚集索引的键就是非聚集索引的叶子节点(在不使用include时). 关于索引的选择 对于索引类型来说没什么好选的,一般来说聚集索引是必须的(有特殊需要的另说),非聚集索引看实际需要灵活建立.因此对于索引来说主要是决定在那些列上建立索引,尤其是对于聚

SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

原文:SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用 近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬.正是受大神们无私奉献精神的影响,所以小弟也作为回报,分享一下关于SET STATISTICS IO和SET STATISTICS TIME这两条T_SQL命令,在查询优化性能中的作用.       首先我想说明一下这篇文章

Sql Server 查询性能优化之走出索引的误区分析_MsSql

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的

Sql Server查询性能优化之不可小觑的书签查找介绍_MsSql

小小程序猿SQL Server认知的成长 1.没毕业或工作没多久,只知道有数据库.SQL这么个东东,浑然分不清SQL和Sql Server Oracle.MySql的关系,通常认为SQL就是SQL Server 2.工作好几年了,也写过不少SQL,却浑然不知道索引为何物,只知道数据库有索引这么个东西,分不清聚集索引和非聚集索引,只知道查询慢了建个索引查询就快了,到头来索引也建了不少,查询也确实快了,偶然问之:汝建之索引为何类型?答曰:... 3.终于受到刺激开始奋发图强,买书,gg查资料终于知道

分析Sql Server查询性能优化之走出索引的误区

误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的观点是错误的,SQL Server查询优化器是基于开销进行选择的优化器,通过一系列复杂判断来决定是否使用索引.使用什么类型索引.使用那个索引.SQL Server内部维护着索引列上的数据的统计,统计信息会随着索引列内容的变化而变化,索引的有效期完全取决于索引列上的统计信息,随着数据的变化关于索引的检索机制也随之变化.对于查询优化器来说始终保持查询开销最低始终是其的不二选择,如果一个非聚集索引的列上有大量的重复值,

MongoDB查询性能优化验证及验证_MongoDB

结论: 1. 200w数据,合理使用索引的情况下,单个stationId下4w数据.mongodb查询和排序的性能理想,无正则时client可以在600ms+完成查询,qps300+.有正则时client可以在1300ms+完成查询,qps140+. 2. Mongodb的count性能比较差,非并发情况下client可以在330ms完成查询,在并发情况下则需要1-3s.可以考虑估算总数的方法,http://blog.sina.com.cn/s/blog_56545fd30101442b.htm

SQL Server 查询性能优化 相关文章

来自: SQL Server 查询性能优化--堆表.碎片与索引(一) SQL Server 查询性能优化--堆表.碎片与索引(二) SQL Server 查询性能优化--覆盖索引(一) SQL Server 查询性能优化--覆盖索引(二) SQL Server 查询性能优化--创建索引原则(一) SQL Server 查询性能优化--创建索引原则(二) SQL Server 查询性能优化--索引与SARG(一) SQL Server 查询性能优化--索引与SARG(二) SQL Server 查

Sql Server 查询性能优化之走出索引的误区分析

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的