CursorLoader 加载联系人 - Android

CursorLoader loading contacts - Android

我正在使用下面的代码,并加载联系人。当联系人大小小于 100 时,一切都很好。我使用选项卡,在其中切换片段。当单击带有联系人的选项卡时,我得到 delay.But 我使用 CursorLoader,但不明白为什么会有延迟。

使用此 class 加载联系人 (ContactFetcher.fetchAll();)

更新!

有一种方法可以使用 LoaderManager 上传联系人,列表 phone 号码(如果联系人有多个)和电子邮件列表?举个例子就好了)

代码如下:

public class ContactFetcher {
    private Context context;

    public ContactFetcher(Context c) {
        this.context = c;
    }

    public ArrayList<MainContact> fetchAll() {
        ArrayList<MainContact> listContacts = new ArrayList<MainContact>();
        CursorLoader cursorLoader = new CursorLoader(context, RawContacts.CONTENT_URI,
                null, // the columns to retrieve (all)
                null, // the selection criteria (none)
                null, // the selection args (none)
                null // the sort order (default)
        );

        Cursor c = cursorLoader.loadInBackground();
        if (c.moveToFirst()) {
            do {
                MainContact contact = loadContactData(c);
                listContacts.add(contact);
            } while (c.moveToNext());
        }
        c.close();
        return listContacts;
    }

    private MainContact loadContactData(Cursor c) {
        // Get Contact ID
        int idIndex = c.getColumnIndex(ContactsContract.Contacts._ID);
        String contactId = c.getString(idIndex);
        // Get Contact Name
        int nameIndex = c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        String contactDisplayName = c.getString(nameIndex);
        MainContact contact = new MainContact(contactId, contactDisplayName, null, null, null, true);
        fetchContactNumbers(c, contact);
        fetchContactEmails(c, contact);
        return contact;
    }

    public void fetchContactNumbers(Cursor cursor, MainContact contact) {
        // Get numbers
        final String[] numberProjection = new String[]{Phone.NUMBER, Phone.TYPE,};

        Cursor phone = new CursorLoader(context, Phone.CONTENT_URI, numberProjection,
                Phone.CONTACT_ID + " = ?", new String[]{String.valueOf(contact.id)}, null)
                .loadInBackground();

        if (phone.moveToFirst()) {
            final int contactNumberColumnIndex = phone.getColumnIndex(Phone.NUMBER);
            final int contactTypeColumnIndex = phone.getColumnIndex(Phone.TYPE);

            while (!phone.isAfterLast()) {
                final String number = phone.getString(contactNumberColumnIndex);
                final int type = phone.getInt(contactTypeColumnIndex);
                String customLabel = "Custom";
                CharSequence phoneType = Phone.getTypeLabel(
                        context.getResources(), type, customLabel);
                contact.addNumber(number, phoneType.toString());
                phone.moveToNext();
            }

        }
        phone.close();
    }

    public void fetchContactEmails(Cursor cursor, MainContact contact) {
        // Get email
        final String[] emailProjection = new String[]{Email.DATA, Email.TYPE};

        Cursor email = new CursorLoader(context, Email.CONTENT_URI, emailProjection,
                Email.CONTACT_ID + "= ?", new String[]{String.valueOf(contact.id)}, null)
                .loadInBackground();

        if (email.moveToFirst()) {
            final int contactEmailColumnIndex = email.getColumnIndex(Email.DATA);
            final int contactTypeColumnIndex = email.getColumnIndex(Email.TYPE);

            while (!email.isAfterLast()) {
                final String address = email.getString(contactEmailColumnIndex);
                final int type = email.getInt(contactTypeColumnIndex);
                String customLabel = "Custom";
                CharSequence emailType = Email.getTypeLabel(
                        context.getResources(), type, customLabel);
                contact.addEmail(address, emailType.toString());
                email.moveToNext();
            }

        }

        email.close();
    }
}

问题是您没有正确使用 CursorLoader。它不应该直接在方法调用中创建或使用,例如 fetchContactNumbers(),它可能是从 ActivityFragment 生命周期回调(如 onResume())调用的。相反,您应该使用 LoaderManager.initLoader() 方法并提供实现 LoaderManager.LoaderCallbacks 的 class。在 onCreateLoader() 回调中是您创建 CursorLoader 的地方,在 onLoadFinished() 中是您检索结果的地方。本文将帮助您了解Loader框架:http://po.st/xHoVMf