0

尝试加载联系人列表时出现性能问题。这是代码:

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("Some column name")); 是否会影响加载时间

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

String.equalsIgnoreCase()

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

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

谢谢

4

2 回答 2

2

除了@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类是否是轻量级的,以及它是否除了初始化其成员之外什么都不做。此外,that ContactList'saddContact方法只是将另一个项目添加到它的 Wrapped 或 ExtendedList<Customer>中。

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

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

于 2012-06-23T18:06:02.317 回答
1

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

于 2012-06-23T16:04:33.077 回答