You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在联系人号码加载代码中设置每200条的分批加载限制?

How to Load Contacts in Batches of 200 Instead of All at Once

Great question! Loading every contact in one go can lead to lag or even ANRs (Application Not Responding) on devices with large contact lists. Let's adjust your code to handle batch loading smoothly:

Step 1: Add Pagination Variables

First, define constants and a variable to track our loading progress:

// Define how many contacts to load per batch
private static final int CONTACTS_PER_BATCH = 200;
// Track where we left off for the next batch
private int currentOffset = 0;

Step 2: Modify the loadContact() Method for Batch Queries

We'll loop to fetch 200 contacts at a time until there are no more contacts left to load. The key change is using LIMIT and OFFSET in the query's sort order to paginate results:

private void loadContact() {
    ContentResolver cr = applicationContext.getContentResolver();
    String[] PROJECTION = ContactsQuery.PROJECTION;

    // Keep loading batches until we run out of contacts
    while (true) {
        // Build the sort order with pagination controls
        // We sort by display name here, but you can use any valid sort column
        String sortOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + 
                          " ASC LIMIT " + CONTACTS_PER_BATCH + 
                          " OFFSET " + currentOffset;

        Cursor cursor = cr.query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            PROJECTION,
            null,
            null,
            sortOrder
        );

        // Exit loop if we get no results or a null cursor
        if (cursor == null || cursor.getCount() == 0) {
            if (cursor != null) cursor.close();
            break;
        }

        // Process each contact in the current batch
        while (cursor.moveToNext()) {
            String lookUpKey = cursor.getString(ContactsQuery.LOOKUP_KEY);
            loadContactDetail(lookUpKey);
        }

        // Clean up the cursor after processing the batch
        cursor.close();

        // Move the offset forward for the next batch
        currentOffset += CONTACTS_PER_BATCH;

        // Optional: If this runs on the UI thread, add a tiny delay to avoid jank
        // (Better yet, move all this logic to a background thread using Coroutines/AsyncTask)
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Bonus: Optimize to Avoid Redundant Queries

Your current loadContactDetail() method makes a separate query for each contact's phone number, which is inefficient. You can modify your projection to include the phone number directly in the initial batch query, cutting out the extra calls:

  1. Update your projection to include the phone number field:
String[] PROJECTION = {
    ContactsQuery.LOOKUP_KEY,
    ContactsContract.CommonDataKinds.Phone.NUMBER // Add this line
};
  1. Remove the loadContactDetail() call and process numbers directly in loadContact():
while (cursor.moveToNext()) {
    String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
    String formatted = Util.formatMSISDN(phone);
    if (formatted != null) {
        contactsSet.add(formatted);
    }
}

This will significantly improve performance by reducing the number of ContentResolver queries.

Important Note: If you're running this code on the main UI thread, make sure to move it to a background thread (using Kotlin Coroutines, Java AsyncTask, or WorkManager) to prevent UI freezes.

内容的提问来源于stack exchange,提问作者asqa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:27:11