提高使用游标获取联系人的速度

问题描述 投票:0回答:1

在我的应用中,我正在使用光标获取所有联系人。

private static final String[] PROJECTION = new String[]{
        PHONE_CONTACT_ID,
        DISPLAY_NAME,
        TIMESTAMP,
        HAS_PHONE_NUMBER};

CursorLoader cursorLoader = new CursorLoader(ResUtils.getInstance().getContext(),
            ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null,
            "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
    Cursor cursor = cursorLoader.loadInBackground();
    // Loop for every contact in the phone
    if (cursor != null && cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            ArrayList<String> phoneNumbers = new ArrayList<>();
            String contact_id = cursor.getString(cursor.getColumnIndex(PHONE_CONTACT_ID));
            String   name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
            String  timeStamp = cursor.getString(cursor.getColumnIndex(TIMESTAMP));
            cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(), ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                    new String[]{EMAIL},ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{contact_id}, null);
            Cursor emailCur = cursorLoader.loadInBackground();
            while (emailCur.moveToNext()) {
                String email = emailCur.getString(emailCur.getColumnIndex(EMAIL));
                if (TmlyUtils.isValidEmail(email)) {
                    phoneNumbers.add(ContactUtils.MAIL_TAG + email);
                }
            }
            emailCur.close();
            if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER))) > 0) {
                cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(),   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[]{NUMBER},ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contact_id}, null);
                Cursor phones = cursorLoader.loadInBackground();
                while (phones.moveToNext()) {
                    String phoneNumber = phones.getString(phones.getColumnIndex(NUMBER));
                    phoneNumber = isValidMobileNumber(phoneNumber);
                    if (!phoneNumber.isEmpty() && !phoneNumbers.contains(ContactUtils.UPN_TAG + phoneNumber)) {
                        phoneNumbers.add(ContactUtils.UPN_TAG + phoneNumber);
                    }
                }
                phones.close();
            }
        }
        cursor.close();
    }

该代码可以正常工作,但是当您有成千上万的联系人时,应用程序会在几秒钟内冻结。

我使用三个光标,第一个允许我获取手机中的所有联系人

CursorLoader cursorLoader = new CursorLoader(ResUtils.getInstance().getContext(),
        ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null,
        "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
Cursor cursor = cursorLoader.loadInBackground();

每个电子邮件地址的第二个循环

 cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(), ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                new String[]{EMAIL},ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{contact_id}, null);
        Cursor emailCur = cursorLoader.loadInBackground();

每个电话的第三个循环

cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(),   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    new String[]{NUMBER},ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contact_id}, null);
            Cursor phones = cursorLoader.loadInBackground();

我需要使用第二个和第三个,如果我不使用它,我将无法获得每个联系人的所有电话和电子邮件,因为一个联系人可以有多个电话和电子邮件地址

我尝试使用CursorLoader加快速度,但这还不够,是否有可能摆脱第二个和第三个光标?

android android-contacts android-cursor android-cursorloader
1个回答
0
投票

如果您的应用程序被冻结,则意味着您的SQL查询在UI线程上运行。使用HandlerThreads,RxJava,Coroutines e.t.c更好地将SQL查询包装为异步代码。这可以帮助您避免阻塞UI线程,从而冻结您的应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.