【问题标题】:Asynchronous operations not performing as expected- Kotlin Android异步操作未按预期执行 - Kotlin Android
【发布时间】:2021-03-20 15:36:20
【问题描述】:

我已经编写了一个从 Cloud Firestore 获取数据的代码,并且正在尝试使用协程来实现网络调用。我尝试尽可能地遵循官方指南,但是由于这些文档中的功能不完整,因此我根据自己的要求进行了调整,但这可能是问题本身。

这是获取数据的函数:

    suspend fun fetchHubList(): MutableLiveData<ArrayList<HubModel>> =  withContext(Dispatchers.IO) {
        val hubList = ArrayList<HubModel>()
        val liveHubData = MutableLiveData<ArrayList<HubModel>>()
        hubsListCollection.get().addOnSuccessListener { collection ->

            if (collection != null) {

                Log.d(TAG, "Data fetch successful!")
                for (document in collection) {
                    Log.d(TAG, "the document id is ")
                    hubList.add(document.toObject(HubModel::class.java))
                }

            } else {
                Log.d(TAG, "No such document")
            }

        }.addOnFailureListener { exception ->
            Log.d(TAG, "get failed with ", exception)
        }


        if (hubList.isEmpty()) {
            Log.d(TAG, "Collection size 0")
        } else {
            Log.d(TAG, "Collection size not 0")
        }
        liveHubData.postValue(hubList)
        return@withContext liveHubData
        }

这是调用此方法的 ViewModel 类:

class HubListViewModel(application: Application): AndroidViewModel(application) {
    // The data which will be observed
    var hubList = MutableLiveData<ArrayList<HubModel>>()
    private val hubListDao = HubListDao()
    init {
        viewModelScope.launch (Dispatchers.IO){
            hubList = hubListDao.fetchHubList()
            Log.d(TAG, "Array List fetched")
        }
    }
}

使用标签消息我知道正在返回一个空列表,我从另一个question of mine 知道,是因为返回的 ArrayList 与获取操作不同步,但我不知道为什么,因为我'已将整个函数包装在 with context 块中。请告诉我为什么没有按顺序执行返回和提取。

【问题讨论】:

    标签: android kotlin kotlin-coroutines android-mvvm


    【解决方案1】:

    你应该添加这个依赖"org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.4.3"。它允许您使用await() 替换回调。

    suspend fun fetchHubList(): List<HubModel>? = try {
        hubsListCollection.get().await().map { document ->
            Log.d(TAG, "the document id is ${document.id}")
            document.toObject(HubModel::class.java)
        }.apply {
            Log.d(TAG, "Data fetch successful!")
            Log.d(TAG, "Collection size is $size")
        }
    } catch (e: Exception) {
        Log.d(TAG, "get failed with ", e)
        null
    }
    

    Dispatchers.IO 不是必需的,因为 firebase API 是主要安全的

    class HubListViewModel(application: Application): AndroidViewModel(application) {
        val hubList = MutableLiveData<List<HubModel>>()
        private val hubListDao = HubListDao()
        init {
            viewModelScope.launch {
                hubList.value = hubListDao.fetchHubList()
                Log.d(TAG, "List fetched")
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 2018-05-29
      • 2019-04-19
      相关资源
      最近更新 更多