簡體   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