【问题标题】:Generics and MutableLiveData in KotlinKotlin 中的泛型和 MutableLiveData
【发布时间】:2019-10-31 17:48:26
【问题描述】:

我有两个非常相似的函数,我试图通过使用泛型来避免代码中的重复。这些函数都有一个 try catch 块,并通过两种不同类型的两个 MutableLiveData 通知其观察者:

val noWasteRecipesPosts: MutableLiveData<List<Recipe>> = MutableLiveData()
val lastArticlesPosts: MutableLiveData<List<Article>> = MutableLiveData()

fun getNoWasteRecipesPosts() {
        makeCall(service.getRecipes(), noWasteRecipesPosts)
        scope.launch {
            try {
                val response = service.getRecipes().await()
                when (response.isSuccessful) {
                    true -> {
                        response.body()?.let {
                            noWasteRecipesPosts.postValue(ArrayList(response.body()))
                        } ?: run {
                            errorLiveData.postValue(response.message())
                        }
                    }
                    false -> errorLiveData.postValue(response.message())
                }
            } catch (e: Exception) {
                noConnectionLiveData.postValue(true)
            }
        }
    }

    fun getLastArticlesPosts(excludeRecipes: Boolean) {
        scope.launch {
            try {
                val response = when (excludeRecipes) {
                    true -> service.getLastArticles(categoriesToExclude = arrayListOf(BlogCategories.NO_WASTE_RECIPES.id))
                        .await()
                    false -> service.getLastArticles()
                        .await()
                }

                when (response.isSuccessful) {
                    true -> {
                        response.body()?.let {
                            lastArticlesPosts.postValue(ArrayList(response.body()))
                        } ?: run {
                            errorLiveData.postValue(response.message())
                        }
                    }
                    false -> errorLiveData.postValue(response.message())
                }
            } catch (e: Exception) {
                noConnectionLiveData.postValue(true)
            }
        }
    }

为了避免代码重复,我尝试使用泛型,但可能以错误的方式。我已经定义了一个函数,它将 Deferred api 响应作为第一个参数,我想传递一个 MutableLiveData 作为第二个参数来通知观察者:

fun makeCall(function: Deferred<Response<*>>, successLiveData: MutableLiveData<*>) {
        scope.launch {
            try {
                val response = function.await()
                when (response.isSuccessful) {
                    true -> {
                        response.body()?.let {
                            successLiveData.postValue(it) // Compile error here
                        } ?: run {
                            errorLiveData.postValue(response.message())
                        }
                    }
                    false -> errorLiveData.postValue(response.message())
                }
            } catch (e: Exception) {
                noConnectionLiveData.postValue(true)
            }
        }

    }

不幸的是,我遗漏了一些东西,IDE 给我一个类型不匹配错误,试图发布 LiveData 值:

类型不匹配:必需:无!找到:任何。

我很困惑,你对 kotlin 中的 MutableLiveData 和泛型有什么建议吗?

【问题讨论】:

    标签: android generics kotlin android-livedata


    【解决方案1】:

    response.body() 类型和MutableLiveData 类型必须匹配。函数签名应该是这样的:

    fun <T> makeCall(function: Deferred<Response<T>>, successLiveData: MutableLiveData<T>)
    

    【讨论】:

    • 感谢您的回复,因此将星形投影替换为 Any 就足够了?我想我已经尝试过了,但没有成功
    • @NicolaGallazzi 为什么是Any?就像在示例中一样输入T,它应该可以工作。请注意,fun &lt;T&gt; 部分将T 定义为类参数。
    • 明白了,现在很清楚了!我明天试试,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2021-04-29
    相关资源
    最近更新 更多