繁体   English   中英

Kotlin 协程在 Android 应用程序中未完成时崩溃

[英]Crash when Kotlin Coroutine Not Complete in Android App

我正在使用 Hilt 依赖项注入从 Firestore 数据库中检索数据。 我有一个 getResources 协程,它在我的 viewModel 中由 init 调用。 在我看来,我试图获取填充数据的前 x 个元素。 但是,该应用程序因此错误而崩溃。

    java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0.
        at kotlin.collections.EmptyList.get(Collections.kt:36)
        at kotlin.collections.EmptyList.get(Collections.kt:24)

我猜测来自 Firestore 的数据加载尚未完成,所以当我尝试获取资源 [i] 时,它是空的并且崩溃了。 即使我进行 null 检查时也会发生这种情况。 如果没有协同程序,我无法初始化{},如果我尝试使用暂停 function,它也不喜欢它。 如何让视图等待视图模型加载数据?

视图模型.kt

@HiltViewModel
class ResourcesViewModel @Inject constructor(
    private val repository: ResourcesRepository
) : ViewModel() {
    val data: MutableState<DataOrException<List<Resource>, Exception>> = mutableStateOf(
        DataOrException(
            listOf(),
            Exception("")
        )
    )

    init {
        getResources()
    }

    private fun getResources() {
        viewModelScope.launch {
            Log.d("getting resources", "currently getting resources")
            data.value = repository.getResourcesFromFireStore()
            Log.d("complete","complete")
        }
    }
}

资源库.kt

@Singleton
class ResourcesRepository @Inject constructor(
    private val db: FirebaseFirestore
) {
    val resources = ArrayList<Resource>()
    suspend fun getResourcesFromFireStore(): DataOrException<List<Resource>, Exception> {
        val resourcesRef: CollectionReference = db.collection("updated-resources-new")
        val dataOrException = DataOrException<List<Resource>, Exception>()
        try {
            dataOrException.data = resourcesRef.get().await().map { document ->
                document.toObject(Resource::class.java)
            }
            Log.d(TAG, "${dataOrException.data}")
        } catch (e: FirebaseFirestoreException) {
            dataOrException.e = e
        }

查看.kt

@Composable
fun ResourcesScreenContent(viewModel: ResourcesViewModel) {
    LazyColumn (
        contentPadding = PaddingValues(horizontal = 10.dp, vertical = 20.dp)
    ) {
        val resources : List<Resource>? = viewModel.data.value.data
        items(30) {
            for (i in 0 ..30) {
                ExpandableCard(resource = resources!![i])
                Divider(thickness = 20.dp, color = Color.White)
            }
        }
    }
}

我该如何解决?

您犯了一个小错误,在forloop 中您使用的是 0...30 ,因此无论资源列表大小如何,它都会运行 30 次。 所以在 for 循环中你必须传递resources.count

@Composable
fun ResourcesScreenContent(viewModel: ResourcesViewModel) {
    LazyColumn (
        contentPadding = PaddingValues(horizontal = 10.dp, vertical =  20.dp)
    ) {
        val resources : List<Resource>? = viewModel.data.value.data
        items(resources.count) { i ->
           
               ExpandableCard(resource = resources!![i])
               Divider(thickness = 20.dp, color = Color.White)
        
        }
    }
}

希望我的兄弟清楚

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM