android联系人列表性能

Posted

技术标签:

【中文标题】android联系人列表性能【英文标题】:android Contact list performance 【发布时间】:2012-06-25 14:43:21 【问题描述】:

我在尝试加载联系人列表时遇到性能问题。 这是代码:

public ContactList getContacts(String constraint)

    ContactList contactList = new ContactList();

    Uri uri = ContactsContract.Contacts.CONTENT_URI;

    if (constraint != null && constraint.equals("") == false)
    
        uri = Uri.withAppendedPath(
                ContactsContract.Contacts.CONTENT_FILTER_URI, constraint);
    

    ContentResolver cr = _context.getContentResolver();
    String sortOrder = DISPLAY_NAME + " COLLATE LOCALIZED ASC";
    // Cursor cur = cr.query(uri, null, null, null, sortOrder);
    String[] arrayOfString = new String[1];
    arrayOfString[0] = "1";
    Cursor cur = cr.query(uri, null, "has_phone_number=?", arrayOfString,
            sortOrder);

    if (cur.getCount() > 0)
    

        setBaseContactList(contactList, cur);

    
    cur.close();

    return contactList;


private void setBaseContactList(ContactList contactList, Cursor cur)

    String id;
    String name;
    String lookUpKey;
    String photoId;
    while (cur.moveToNext())
    
        id = cur.getString(cur.getColumnIndex(DISPLAY_ID));
        name = cur.getString(cur.getColumnIndex(DISPLAY_NAME));

        photoId = cur.getString(cur.getColumnIndex(PHOTO_ID));
        lookUpKey = cur.getString(cur.getColumnIndex(LOOKUP_KEY));
        Contact c = new Contact(id, name, photoId, lookUpKey);
        contactList.addContact(c);
    

查看 traceview 我可以看到 cur.getString(cur.getColumnIndex("某个列名")); 会影响加载时间

在使用 traceview 时我可以看到的另一件事是该方法有很多调用

String.equalsIgnoreCase()

我的猜测是 cur.getString 正在调用它。

我正在考虑将所有启动的值 onCreate() 放在 HT(ContactID, Contact) 中,然后在每次从联系人数据库中选择之后调用它们提取的用户 ID。 我将减少使用量 3 次,这很好,但有更好的解决方案吗?

谢谢

【问题讨论】:

【参考方案1】:

除了@wildhemp 的建议之外,我还将尝试查询特定列,而不是为所有列传递“null”。如果我从硬编码索引中获取值,我还将检查将节省多少周期(不是最佳实践,但可能会加快处理速度)。 例如:

Cursor cur = cr.query(uri, 
                      new String[] DISPLAY_ID, DISPLAY_NAME, PHOTO_ID, LOOKUP_KEY,
                      "has_phone_number=?", arrayOfString, sortOrder);
while (cur.moveToNext())

    id = cur.getString(0);
    name = cur.getString(1);
    photoId = cur.getString(2);
    lookUpKey = cur.getString(3);

    Contact c = new Contact(id, name, photoId, lookUpKey);
    contactList.addContact(c);

我要检查的另一件事是在没有任何排序的情况下进行查询,有趣的是看看它使用了多少额外的循环进行排序,也许还有另一种更有效的方法来做到这一点。

虽然这很明显,但我仍然会问Customer 类是否是轻量级的,以及它是否除了初始化其成员之外什么都不做。此外,ContactListaddContact 方法只是将另一个项目添加到其包装或扩展的List<Customer>

一般注意,最好用 try/catch/finally 包围任何与游标相关的工作,以确保完成后关闭游标。

无论如何,在处理诸如此类的问题时,要么是查询效率低下,要么是解析循环出错了

【讨论】:

我听从了你的指示。参考:Although this is quite obvious i would still ask whether the Customer class is lightweight and if it does nothing but initializes its members. Also, that ContactList's addContact method simply adds another item to its wrapped or extended List<Customer>. 正如你所说-轻量级。但是,按照您的建议,我将创建列表所需的时间缩短到 46 毫秒。我添加了 traceview 分析也许这会有所帮助。 traceview. 抱歉,我无法从您的转储中获得任何相关信息,它仅显示创建联系人列表所需的时间(根据您的标记)以及绘制过程中花费的时间。您是否在期间或之后立即绘制任何东西?另一方面,如果您可以避免在每次迭代中创建新对象(不要使用关键字“new”),它将为您节省更多的 CPU 周期【参考方案2】:

我会说equalsIgnoreCase 是从cur.getColumnIndex 调用的。如果不是在 while 循环中每次都调用它们,而是只调用它们一次并存储它们,那么你可以让它更快。

【讨论】:

这是我提出的解决方案(查看最后一段)

以上是关于android联系人列表性能的主要内容,如果未能解决你的问题,请参考以下文章

Android:联系人列表有重复的名字

Android 获取联系人列表未在 Android 10 中显示

如何从 Android 中的联系人列表中获取联系人?使用联系提供商

列表视图上的 Android 联系人

列表视图上的 Android 联系人

Android带索引联系人列表