简体   繁体   English

如何在android上的listview中快速加载联系人

[英]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+.联系人数量为 1000+。 i get the contacts我得到了联系方式

by using ContentResolver query that is cr.query(...),store the values in an arraylist通过使用 cr.query(...) 的ContentResolver 查询,将值存储在一个数组列表中

and after that load the array list in setListAdapter(...).然后在 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.应用程序需要将近 1 分钟,所以我使用异步任务,但使用异步任务没有太大区别。

i need to display all contacts within 2 to 4 seconds.我需要在 2 到 4 秒内显示所有联系人。 i check in the default contacts application on android simulator which is load within in 2 to 4 seconds.我检查了android 模拟器上默认联系人应用程序,它会在 2 到 4 秒内加载。 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));
            ... 
       }

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.这太神奇了:我的程序速度几乎降低了 200 倍,并且操作对用户完全不可见。

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.如果我没记错的话,默认的 android 列表也会做同样的事情 - 它只显示名称,然后加载所有其他与联系人相关的数据。

我使用游标适配器并剪切了数据库、数组适配器并优化了代码。

Use the Concept of projections and selection arguments to retrive the contacts in my case for 500 contacts intially it was taking 12 sec.使用投影和选择参数的概念来检索我的案例中的联系人,最初需要 12 秒的 500 个联系人。

Now it is taking 350ms(lessthan second)现在需要 350 毫秒(不到一秒)

void getAllContacts() {
    long startnow;
    long endnow;

    startnow = android.os.SystemClock.uptimeMillis();
    ArrayList arrContacts = new ArrayList();

    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
    Cursor cursor = ctx.getContentResolver().query(uri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER,   ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.Contacts._ID}, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");

    cursor.moveToFirst();
    while (cursor.isAfterLast() == false) {

        String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        int phoneContactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
        int contactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
        Log.d("con ", "name " + contactName + " " + " PhoeContactID " + phoneContactID + "  ContactID " + contactID)

        cursor.moveToNext();
    }
    cursor.close();
    cursor = null;

    endnow = android.os.SystemClock.uptimeMillis();
    Log.d("END", "TimeForContacts " + (endnow - startnow) + " ms");
}

More information on this link http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html ....有关此链接的更多信息http://www.blazin.in/2016/02/loading-contacts-fast-from-android.html ....

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:您可以通过使用 Content Uri 进行查询来提高速度:

"ContactsContract.CommonDataKinds.Phone.CONTENT_URI"

This URI also has the "ContactsContract.Contacts.DISPLAY_NAME" field.此 URI 还具有“ContactsContract.Contacts.DISPLAY_NAME”字段。

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.这对我有用。

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...:)干杯...:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM