我正在尝试获取联系人的数据(姓名、号码和照片 URI),但速度太慢,在查看 UI 之前显示黑屏几秒钟。当尝试在单独的线程中执行此操作时,以下错误似乎将进程移至主线程。如果有人可以帮助解决这个问题, 谢谢...
private fun checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CONTACTS), 100)
} else {
getContactList()
}
}
private fun getContactList() {
val uri: Uri = ContactsContract.Contacts.CONTENT_URI
// Sort by ascending
val sort: String = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC"
// Initialize Cursor
val cursor: Cursor = this.contentResolver.query(uri, null, null, null, sort)!!
// Check condition
if (cursor.count > 0) {
while (cursor.moveToNext()) {
val name: String = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME))
val img = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.PHOTO_URI))
val phoneUri: Uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
// Initialize phone cursor
val phoneCursor: Cursor = this.contentResolver.query(phoneUri,
null, null, null, sort)!!
// Check condition
if (phoneCursor.moveToNext()) {
val number: String = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER))
// Initialize Contact Model
val model = ContactModel(name, number, img)
contactArr.add(model)
groupListAdapter.notifyDataSetChanged()
// Close Phone Cursor
phoneCursor.close()
}
}
// Close Cursor
cursor.close()
}
}
lifecycleScope.launch { checkPermission() }
您正在尝试更新每个项目的整个适配器。将所有内容收集到列表中然后更新适配器会更有意义。
您可以在 IO 调度程序上运行大部分工作,以防加载联系人需要一段时间,并使用 Main 调度程序触摸视图。您可以使用
withContext
. 切换调度员
您也无法在所有条件下关闭游标——您是在 if 语句中执行此操作,因此如果条件为假,则您正在泄漏游标。
修复了上述问题的函数版本:
private fun getContactList() = lifecycleScope.launch(Dispatchers.IO) {
val uri: Uri = ContactsContract.Contacts.CONTENT_URI
// Sort by ascending
val sort: String = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC"
val cursor: Cursor = this.contentResolver.query(uri, null, null, null, sort)
?.takeIf { it.count > 0) ?: run {
Log.w(TAG, "No contracts returned.")
return@launch
}
while (cursor.moveToNext()) {
val name: String = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME))
val img = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.PHOTO_URI))
val phoneUri: Uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
val phoneCursor: Cursor = this.contentResolver.query(phoneUri, null, null, null, sort)
if (phoneCursor != null && phoneCursor.moveToNext()) {
val number: String = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER))
val model = ContactModel(name, number, img)
contactArr.add(model)
}
phoneCursor?.close()
}
cursor.close()
withContext(Dispatchers.Main) { groupListAdapter.notifyDataSetChanged() }
}