黑屏和启动应用程序时启动慢,当将联系信息获取到RecyclerView时?

huangapple go评论65阅读模式
英文:

Black screen and slow startup on starting app, when getting contact information into a RecyclerView?

问题

我在获取联系信息并放入RecyclerView时遇到了启动缓慢和黑屏的问题。当删除该进程时,问题消失了。以下是getContacts函数的内容,如果有人能帮忙,谢谢...

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 = requireActivity().contentResolver.query(uri, null, null, null, sort)!!
    // Check condition
    if (cursor.count > 0) {
        while (cursor.moveToNext()) {
            val id: String = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID))
            val name: String = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))
            val img: String = getPhotoUriFromID(id).toString()
            val phoneUri: Uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
            val selection: String = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " =?"
            // Initialize phone cursor
            val phoneCursor: Cursor = requireActivity().contentResolver.query(phoneUri, null, selection,
                arrayOf(id), null)!!
            // 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()
    }
}
英文:

I have a problem with a slow start and black screen when getting contact information into RecyclerView. And, the problem is gone when deleting the process. Below is the function of getContacts, if anyone can help. Thank you...

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 = requireActivity().contentResolver.query(uri, null, null, null, sort)!!
        // Check condition
        if (cursor.count > 0) {
            while (cursor.moveToNext()) {
                val id: String = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID))
                val name: String = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))
                val img: String = getPhotoUriFromID(id).toString()
                val phoneUri: Uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
                val selection: String = ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" =?"
                // Initialize phone cursor
                val phoneCursor: Cursor = requireActivity().contentResolver.query(phoneUri, null, selection,
                    arrayOf(id), null)!!
                // 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()
        }
    }

答案1

得分: 2

你的代码中存在两个主要问题:

  1. 你很可能是在UI线程上运行上述查询,这会阻塞整个手机,直到查询完成加载,这对用户体验非常不好。
  2. 你的代码首先运行一个查询来获取所有联系人,然后对每个联系人运行更多的查询,这意味着如果你的用户有5000个联系人,你的代码将需要运行5000个查询,这可能需要很长时间才能完成。

要解决问题#1,你应该以异步方式调用你的代码,并在查询完成后更新你的RecyclerView,以在屏幕上加载你的项目。

有许多方法可以做到这一点,可以简单使用AsyncTask,也可以更高级一些,如AsyncListUtil

以下是一些资源:

  1. https://androidwave.com/implementation-of-recyclerview-with-cursor-adapter/
  2. https://medium.com/android-news/how-to-use-asynclistutil-16b5175bb468

问题#2可以通过直接在ContactsContract.Data表上运行查询来解决,而不是在ContactsContract.Contacts表上运行查询。

Data表包含所有联系人的所有信息,因此你可以通过一个大查询获取所有需要的信息,这比多个较小的查询要快得多。

以下是如何做到这一点的示例:https://stackoverflow.com/a/52602698/819355

英文:

You have two major issues in your code:

  1. You're probably running the above queries on the UI thread which blocks the entire phone until the query finishes loading, which is really bad user-experience.
  2. Your code runs one query to fetch all contacts, and then more queries per contact, that means if your user has 5000 contacts your code will need to do 5000 queries which can take a long time to complete.

To fix issue #1, you should call your code asynchronously and update your RecyclerView when the query finishes to load your items on screen.

There are many ways to do this,
as simply as an AsyncTask, and more advanced like AsyncListUtil

here are some resources:

  1. https://androidwave.com/implementation-of-recyclerview-with-cursor-adapter/
  2. https://medium.com/android-news/how-to-use-asynclistutil-16b5175bb468

Issue #2 can be fixed by running your query directly on the ContactsContract.Data table instead of the ContactsContract.Contacts table.

The Data table contains all information on all contacts, so you can get all your need in one big query which is much faster then multiple smaller queries.

Here's an example on how to do that: https://stackoverflow.com/a/52602698/819355

huangapple
  • 本文由 发表于 2023年4月4日 11:33:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925314.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定