Kotlin 中的泛型和 MutableLiveData
Generics and MutableLiveData in Kotlin
我有两个非常相似的函数,我试图通过使用泛型来避免代码中的重复。这些函数都有一个 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 给我一个类型不匹配错误,试图 post LiveData 值:
Type mismatch: Required : Nothing! Found: Any.
我很困惑,你对 kotlin 中的 MutableLiveData 和泛型有什么建议吗?
response.body()
类型和 MutableLiveData
类型必须匹配。函数签名应该是这样的:
fun <T> makeCall(function: Deferred<Response<T>>, successLiveData: MutableLiveData<T>)
我有两个非常相似的函数,我试图通过使用泛型来避免代码中的重复。这些函数都有一个 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 给我一个类型不匹配错误,试图 post LiveData 值:
Type mismatch: Required : Nothing! Found: Any.
我很困惑,你对 kotlin 中的 MutableLiveData 和泛型有什么建议吗?
response.body()
类型和 MutableLiveData
类型必须匹配。函数签名应该是这样的:
fun <T> makeCall(function: Deferred<Response<T>>, successLiveData: MutableLiveData<T>)