通讯录阅读时间 Android

Contact book read time on Android

我编写了以下查询以从设备读取联系人。

private fun getContactPhoneNumbers(resolver: ContentResolver): Map<String, NameAndPhoneList> {
        val startTime = System.nanoTime()
        val map = hashMapOf<String, NameAndPhoneList>()
        val projection = arrayOf(
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.HAS_PHONE_NUMBER,
            ContactsContract.Contacts.PHOTO_THUMBNAIL_URI
        )
        val selection =
            "${ContactsContract.Contacts.DISPLAY_NAME} NOT LIKE '' and ${ContactsContract.Contacts.DISPLAY_NAME} NOT NULL"
        resolver.query(
            ContactsContract.Contacts.CONTENT_URI,
            projection,
            selection,
            null,
            null,
            null
        )?.let { cursor ->
            if (cursor.count > 0) {
                while (cursor.moveToNext()) {
                    val id: String? =
                        cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
                    val name: String? =
                        cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
                    val photoUri =
                        cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI))
                    val phone =
                        if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
                            val pCur: Cursor = resolver.query(
                                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                                arrayOf(id),
                                null
                            )!!
                            val numbers = mutableListOf<String>()
                            while (pCur.moveToNext()) {
                                val phoneNo: String = pCur.getString(
                                    pCur.getColumnIndex(
                                        ContactsContract.CommonDataKinds.Phone.NUMBER
                                    )
                                )
                                numbers.add(phoneNo)
                            }
                            pCur.close()
                            numbers
                        } else
                            null
                    // take contacts which either have email or phone numbers
                    if (id != null && name != null) {
                        map[id] = NameAndPhoneList(name, phone, photoUri?.let { Uri.parse(it) })
                    }
                }
            }
            cursor.close()
        }
        val endTime = System.nanoTime() - startTime
        Timber.i("$CONTACT_SYNC_PHONE_MAP_QUERY_TIME = $endTime")
        return map
    }

    private data class NameAndPhoneList(
        val name: String,
        val phoneList: List<String>?,
        val imageUri: Uri?
    )

对于长度为 6,300 个联系人的电话簿,这需要 112877872699 纳秒(~2 分钟)。这是预期的还是我们可以进一步优化?

对于 6,300 个联系人(假设所有人都有一个 phone),您要进行 6,301 个查询,这就是为什么它这么慢的原因...

相反,您可以受益于 ContactsContract 的“implicit join”功能,它允许您在查询 Data.CONTENT_URI table.[=16= 时获取 Contacts.CONTENT_URI 字段]

所以,直接查询数据table,得到所有phone包括CONTACT_IDDISPLAY_NAME等字段,然后放入一些地图联系人 ID => 数据。

Java 中的示例代码可以提供帮助 -