【问题标题】:Fastest way to query contacts with "mobile phone numbers" on AndroidAndroid上用“手机号码”查询联系人的最快方法
【发布时间】:2011-05-19 23:36:18
【问题描述】:

我需要获取设备中所有联系人及其电话号码的不同列表。但是等等......我们知道有些联系人可能分配了多个号码,这完全取决于每个用户如何存储他的联系人。这是我的工作:

    ContentResolver cr = context.getContentResolver();   
    Uri uri = ContactsContract.Contacts.CONTENT_URI;
    String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };
    String selection =  ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'";
    String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
    ArrayList<user> contacts = new ArrayList<user>();

    Cursor users = a.managedQuery(uri, projection, selection, null, sortOrder);

    while (users.moveToNext()) {
        user u = new user();
        u.PhoneId = users.getInt(users.getColumnIndex(ContactsContract.Contacts._ID));
        u.Name = users.getString(users.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

        String homePhone = "", cellPhone = "", workPhone = "", otherPhone = "";
        Cursor contactPhones = cr.query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + u.PhoneId, null, null);

        while (contactPhones.moveToNext()) {

            String number = contactPhones.getString(contactPhones.getColumnIndex(Phone.NUMBER));
            int type = contactPhones.getInt(contactPhones.getColumnIndex(Phone.TYPE));
            switch (type) {
                case Phone.TYPE_HOME:   homePhone = number; break;
                case Phone.TYPE_MOBILE:  cellPhone = number; break;
                case Phone.TYPE_WORK:   workPhone = number; break;
                case Phone.TYPE_OTHER:  otherPhone = number; break;
                }
        }        
        u.Phone = ((cellPhone!="") ? cellPhone : ((homePhone!="") ? homePhone : ((workPhone!="") ? workPhone : otherPhone)));
    }

    return contacts;

这个过程有效,但对于我的 80 个联系人来说,它需要 1000-2000 毫秒,我需要更快地工作:)

【问题讨论】:

  • 我想问一下你为什么要做u.Phone = ((cellPhone!="")?cellPhone:(((homePhone!="")?homePhone:(workPhone!="")?workPhone:otherPhone)));这样的事情。这使您的代码比“正确”格式化更难阅读。另外,您是否对此代码运行了跟踪视图以找出实际运行缓慢的原因?
  • @Austyn Mahoney:内联 if 是对数字进行优先级排序,而不是执行 10 行 if/else :) 减慢速度的是每个联系人的数字的“.query”。如果只有一种方法可以一次查询所有这些信息……
  • 我认为不存在更快的方法来做到这一点。我不得不做类似的事情。我相信,您必须遍历所有联系人并对其进行处理。

标签: android performance contacts


【解决方案1】:
Cursor contactPhones = cr.query(Phone.CONTENT_URI, null, 
                                Phone.CONTACT_ID + " = " + u.PhoneId, 
                                null, 
                                null);

这不是最理想的,因为您直接在查询中对联系人 ID 字段进行编码,而不是使其成为参数。这意味着查询解析器每次都必须重新解析查询,而不是能够使用单个缓存副本。

改为提供 ID 作为参数:

Cursor contactPhones = cr.query(Phone.CONTENT_URI, null, 
                                Phone.CONTACT_ID + " =? ", 
                                new String[] { Integer.toString(u.PhoneId) }, 
                                null);

ContentResolver.query()javadoc 重申了这一指导:

使用问号参数标记,例如“phone=?”代替 选择参数中的显式值,以便查询 仅通过这些值不同将被识别为相同的缓存 目的。

【讨论】:

    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    相关资源
    最近更新 更多