M.A.Murali
M.A.Murali

Reputation: 10148

How to fast the contacts loading in listview on android

in my app i am listing contacts in a listview. no of contacts is 1000+. i get the contacts

by using ContentResolver query that is cr.query(...),store the values in an arraylist

and after that load the array list in setListAdapter(...). to display the all contacts my

apps takes nearly 1 minute so that i use Async task but there is no big differences by using the async task.

i need to display all contacts within 2 to 4 seconds. i check in the default contacts application on android simulator which is load within in 2 to 4 seconds. i have spend

long time in google. but i could not get any helpful solution. please help me how to fast the loading contacts on listview. please help me.

my coding sample:

    private ArrayList<ContactListEntry> loadContactListInternal(String searchString) {
        ArrayList<ContactListEntry> contactList = new ArrayList<ContactListEntry>();
    ContentResolver cr = getContentResolver();
    Cursor cur = null;
    String[] projection = new String[] {BaseColumns._ID,ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts.PHOTO_ID};
    ....
        cur=cr.query(ContactsContract.Contacts.CONTENT_URI, projection, selection, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");

    while (cur.moveToNext()) {
         int id = Integer.parseInt(cur.getString(0));
             ....   
        if (input !=null)
            photo = BitmapFactory.decodeStream(input);
         ....
        ArrayList<ContactListEntry.PhoneEntry> phoneEntries = new ArrayList<ContactListEntry.PhoneEntry>();

            String[] projection1 = new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.TYPE};    
            Cursor pcur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,projection1, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { String.valueOf(id) }, null);
            while (pcur.moveToNext()) {
                ...
            }
            pcur.close();

            ContactListEntry entry = new ContactListEntry(id, name, photo, phoneEntries);
            contactList.add(entry);
    }
    cur.close();

    return contactList;
}
    .....
    in another class
        private void selectionUpdated() {
                ....
         setListAdapter(new SelectedArrayAdapter(this, app.selectedContacts));
            ... 
       }

Upvotes: 2

Views: 4213

Answers (4)

Melbourne Lopes
Melbourne Lopes

Reputation: 4855

OPTIMIZED SOLUTION HERE.....

private static final String[] PROJECTION = new String[] {
        ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Phone.NUMBER
    };
.
.
.

ContentResolver cr = getContentResolver();
        Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);
        if (cursor != null) {
            try {
                final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
                final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

                String name, number;
                while (cursor.moveToNext()) {
                    name = cursor.getString(nameIndex);
                    number = cursor.getString(numberIndex);
                }
            } finally {
                cursor.close();
            }
        }

CHEERS...:)

Upvotes: 0

Jimmy Ilenloa
Jimmy Ilenloa

Reputation: 2009

Consider having just one query and getting rid of the sub query idea (as already suggested). You can achieve speed by just querying using the Content Uri:

"ContactsContract.CommonDataKinds.Phone.CONTENT_URI"

This URI also has the "ContactsContract.Contacts.DISPLAY_NAME" field.

You might also want to consider doing this query and working with your adapter in a seperate thread to make it completely transparent.

This worked for me.

Upvotes: 0

M.A.Murali
M.A.Murali

Reputation: 10148

i use cursor adapter and i cut the databse,arrayadapter and optimize the code.

Upvotes: 1

Boris Strandjev
Boris Strandjev

Reputation: 46943

So your problem is that you do a lot of subqueries for each contact. I has the same issue once upon a time. My case was that I showed many contacts and allowed the user to click on any of them. After that I started processing the contact in another activity.

Back then I finally decided that I should display only the name and lazily fetch all the other data later on, just before I launch the next activity. This was amazing: decreased the speed of my program almost by a factor of 200, and the operations became completely invisible to the user.

The default android list does the same if I am not wrong - it displays only the name, and later on loads all the other contact-related data.

Upvotes: 1

Related Questions