0

In my Android application, an Activity is to display the list of contacts in the user's phone. The issue is that the operation takes about 3 seconds to execute, needless to say this is completely unacceptable. Here is the code I used:

private List<Contact> retrieveContacts(ContentResolver contentResolver) {
        LinkedHashSet<Contact> contactSet = new LinkedHashSet<Contact>();
        List<Contact> listContacts = new ArrayList<Contact>();
        final Cursor cursor = contentResolver.query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                new String[] {
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER }, null,
                null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
        if (cursor == null);
        if (cursor.moveToFirst() == true) {
            do {
                final String name = cursor
                        .getString(cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                final String telephone = cursor
                        .getString(cursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                Contact contact = new Contact(telephone, name, false, false);
                contactSet.add(contact);

            } while (cursor.moveToNext() == true);
        }

        if (cursor.isClosed() == false) {
            cursor.close();
        }
        for (Contact contact : contactSet){
            listContacts.add(contact);
        }
        return listContacts;
    }

I then populate a ListView with the result of retrieveContacts. I'm using LinkedHashSet because it doesn't accept duplication and it keeps the order used to add elements. (I needed to retain that order)

Is this standard for such a query to take that much time? Is there any way to improve its performance?

Kritias
  • 187
  • 1
  • 12
  • "much time"? how many contacts do you have and how "much time" is it? – pskink May 21 '15 at 19:08
  • I mentionned 3 seconds in my question. In my case there is about one hundred contacts, I think it's not that big. – Kritias May 21 '15 at 19:45
  • hmmm, it should take < **100 ms** (**0.1** sec), not **3** sec, not **1** sec, see my answer here: http://stackoverflow.com/a/26820544/2252830, it not only gets name and phone numbers but also email accounts – pskink May 22 '15 at 07:35

1 Answers1

0

You can use some optimizations to improve performance of your code. Though I think it would be minor.

  1. Store index of name and number column after getting it once
  2. You can remove last for loop with ArrayList constructor implementation.

Here's how I would write this code:

private List<Contact> retrieveContacts(ContentResolver contentResolver) {
    LinkedHashSet<Contact> contactSet = new LinkedHashSet<Contact>();
    final Cursor cursor = contentResolver.query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            new String[] {
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.NUMBER }, null,
            null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
    if (cursor == null);
    if (cursor.moveToFirst()) {
        int nameIndex = cursor
                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
        int phoneIndex = cursor
                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
        do {
            final String name = cursor
                    .getString(nameIndex);
            final String telephone = cursor
                    .getString(phoneIndex);
            Contact contact = new Contact(telephone, name, false, false);
            contactSet.add(contact);

        } while (cursor.moveToNext());
    }

    if (!cursor.isClosed()) {
        cursor.close();
    }

    return new ArrayList<Contact>(contactSet);
}
jimmy0251
  • 16,293
  • 10
  • 36
  • 39
  • 1
    Actually it did improve things, the execution takes approximately 1 second now, which is quite better! Thank you for that. – Kritias May 21 '15 at 19:43