我刚刚开始实现MVVM 架构
我有一个这样的存储库:
object ConfigsSSOT {
val liveData: MutableLiveData<DataWrapper<ConfigsResponse>> = MutableLiveData<DataWrapper<ConfigsResponse>>()
fun initConfigs() {
liveData.value = DataWrapper.loading()
RetrofitBuilder.createConfigs().mainConfigs(
BuildConfig.VERSION_CODE,
SettingsSSOT.getTimestamp(),
TranslationsSSOT.getTimestamp(),
CitySSOT.getTimestamp()
).enqueue(ApiCallback(liveData))
}
}
在视图模型中我有这个:
private val _configsLiveData: MutableLiveData<DataWrapper<ConfigsResponse>> = SSOT.configsSSOT.liveData
private val _shouldUpdateLiveData: LiveData<Boolean> = Transformations.map(_configsLiveData, ::_mapShouldUpdate)
private fun _mapShouldUpdate(configs: DataWrapper<ConfigsResponse>): Boolean {
return (configs.status != TStatus.LOADING && configs.data?.shouldUpdate ?: false)
}
fun initConfigs() {// !!!!!!!! This is what I call from the Fragment to make the API call
ConfigsSSOT.initConfigs()
}
我的问题是,暴露的 liveDataConfigsSSOT
可能会在另一个中使用Fragment
,另一个可以调用 initConfigs() (假设使用其他值)但是因为 Repository 是一个单例,它会返回相同的 liveData 对象。我不想要那个。
一个解决方案是在每次调用时创建一个新的 liveData 对象,即
object ConfigsSSOT {
fun initConfigs() : MutableLiveData<DataWrapper<ConfigsResponse>>{
var liveData: MutableLiveData<DataWrapper<ConfigsResponse>> = MutableLiveData<DataWrapper<ConfigsResponse>>()
liveData.value = DataWrapper.loading()
RetrofitBuilder.createConfigs().mainConfigs(
BuildConfig.VERSION_CODE,
SettingsSSOT.getTimestamp(),
TranslationsSSOT.getTimestamp(),
CitySSOT.getTimestamp()
).enqueue(ApiCallback(liveData))
return liveData
}
}
但是现在出现了2个问题。
1.我需要重做这一行_shouldUpdateLiveData = Transformations.map(_configsLiveData, ::_mapShouldUpdate)
,因为 viewModel 中的 _configsLiveData 已更改
即是这样的:
fun initConfigs() : MutableLiveData<DataWrapper<ConfigsResponse>> {
liveData = ConfigsSSOT.initConfigs()
_shouldUpdateLiveData = Transformations.map(_configsLiveData, ::_mapShouldUpdate)
return liveData
}
这似乎是一个非常糟糕的做法,而且......如果我的布局(xml)检索并观察了 liveData 但是我用另一个实例替换了那个 liveData 实例,xml 将观察到永远不会被再次调用的东西
2.那不是意味着 LiveData 对象会被泄露吗?如果我为每次调用生成新的,假设用户按下一个按钮,我每次都进行 API 调用并每次生成一个新的 LiveData 对象,那么旧的会发生什么?!
需要帮助: 我找不到该场景的任何解决方案和最佳实践:使用相同的存储库进行 API 调用,使用存储库中的 liveData 将数据发送回“viewModel 调用者”,但不要为每个调用实例化 liveData ,而是以某种方式使用相同的,但是当从不同的视图模型进行调用时,不要使用相同的 liveData 调用。
所以,所以,令人困惑!
编辑
由于评论部分中的一些讨论,添加了 RetrofitBuilder
object RetrofitBuilder {
private val _okHttpClient = OkHttpClient().newBuilder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.cache(null)
.build()
private val _retrofitBuilderMill = Retrofit.Builder()
.baseUrl(BuildConfig.URL_BASE + "/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(_okHttpClient)
.build()
private val _retrofitBuilderPizza = Retrofit.Builder()
.baseUrl("https://www.validator.pizza")
.addConverterFactory(GsonConverterFactory.create())
.client(_okHttpClient)
.build()
fun <S> createGenericService(serviceClass: Class<S>?): S {
return _retrofitBuilderMill.create(serviceClass)
}
fun createPizza(): PizzaApiService {
return _retrofitBuilderPizza.create(PizzaApiService::class.java)
}
fun createConfigs(): ConfigsApiService {
return createGenericService(ConfigsApiService::class.java)
}
fun createAuth(): AuthApiService {
return createGenericService(AuthApiService::class.java)
}
}