Данные Recyclerview не извлекаются с помощью сопрограмм - PullRequest
2 голосов
/ 05 мая 2020

Я пытаюсь отобразить данные хранилища Firebase в recyclerview с помощью сопрограмм. Когда я это делаю, он не показывает изображения, он отображает пустой recyclerview. Вот код

private var imageList = ArrayList<ImageItem>()

onCreate() {
    ....
    CoroutineScope(Dispatchers.Main).launch {
        getImages()
        updateAdapter()
    }

}

private suspend fun getImages() =
    withContext(Dispatchers.IO) {
        storageReference.listAll().addOnSuccessListener { listResult ->
            listResult.items.forEach { storageRef ->
                storageRef.downloadUrl.addOnSuccessListener {
                    imageList.add(ImageItem(it))
                }
            }
        }
}

private suspend fun updateAdapter() {
    withContext(Dispatchers.Main) {
        adapter.notifyDataSetChanged()
    }
}

, когда я помещаю delay (1000) в конец getImages (), данные отображаются правильно. Пожалуйста, помогите

1 Ответ

1 голос
/ 05 мая 2020

addOnSuccessListener не будет вызываться одновременно с назначением, сопрограмма завершится до завершения. Вы можете вызвать updateAdapter после forEach l oop.

Пример:

// onCreate
CoroutineScope(Dispatchers.Main).launch {
    getImages()
}

private suspend fun getImages() =
    withContext(Dispatchers.IO) {
        storageReference.listAll().addOnSuccessListener { listResult ->
            listResult.items.forEach { storageRef ->
                storageRef.downloadUrl.addOnSuccessListener {
                    imageList.add(ImageItem(it))
                }
            }
            updateAdapter()
        }
    }

Или вы можете использовать suspendCoroutine, если вы хотите использовать ту же архитектуру, которую используете в настоящее время.

// onCreate
CoroutineScope(Dispatchers.Main).launch {
    getImages()
    updateAdapter()
}

private suspend fun getImages() =
    withContext(Dispatchers.IO) {
        suspendCoroutine { cont ->
            storageReference.listAll().addOnSuccessListener { listResult ->
                listResult.items.forEach { storageRef ->
                    storageRef.downloadUrl.addOnSuccessListener {
                        imageList.add(ImageItem(it))
                    }
                }
                cont.resume(Unit)
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...