我有这样的存储库设置
//EXAMPLE
let heightMeters = Measurement(value: 16.99, unit: UnitLength.meters)
let heightCentimeters = heightMeters.converted(to: UnitLength.centimeters)
//EXTRACT CM FROM METERS BY EVALUATING THE DECIMAL PART
let cm = ceil((heightMeters.value - floor(heightMeters.value))*100)
// GET METERS WITHOUT CM
let meters = floor(heightMeters.value)
let heightInches = heightMeters.converted(to: UnitLength.inches)
let heightFeet = heightMeters.converted(to: UnitLength.feet)
//EXTRACT INCHES FROM FT BY EVALUATING THE DECIMAL PART
let inches = ceil((heightFeet.value - floor(heightFeet.value))*12)
// GET FT WITHOUT INCHES
let feet = floor(heightFeet.value)
然后我有一个像这样的视图模型调用此仓库
class ServerTimeRepo @Inject constructor(private val retrofit: Retrofit){
var liveDataTime = MutableLiveData<TimeResponse>()
fun getServerTime(): LiveData<TimeResponse> {
val serverTimeService:ServerTimeService = retrofit.create(ServerTimeService::class.java)
val obs = serverTimeService.getServerTime()
obs.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).unsubscribeOn(Schedulers.io())
.subscribe(object : Observer<Response<TimeResponse>> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: Response<TimeResponse>) {
val gson = Gson()
val json: String?
val code = t.code()
val cs = code.toString()
if (!cs.equals("200")) {
json = t.errorBody()!!.string()
val userError = gson.fromJson(json, Error::class.java)
} else {
liveDataTime.value = t.body()
}
}
override fun onError(e: Throwable) {
}
})
return liveDataTime
}
}
然后我有一个活动,其中有一个onClickListener,用于观察实时数据,就像这样
class ServerTimeViewModel @Inject constructor(private val serverTimeRepo: ServerTimeRepo):ViewModel() {
fun getServerTime(): LiveData<TimeResponse> {
return serverTimeRepo.getServerTime()
}
}
我不知道这有什么问题。谁能指出我正确的方向?谢谢。
答案 0 :(得分:0)
问题是,每次您的 ClickListener 被解雇时,您就会一次又一次地观察到LiveData
。因此,您可以按照以下解决方案来解决该问题:
在您的MutableLiveData
内私下放置一个ViewModel
对象,并以LiveData
的身份观察。
class ServerTimeViewModel @Inject constructor(private val serverTimeRepo: ServerTimeRepo):ViewModel() {
private val serverTimeData = MutableLiveData<TimeResponse>() // We make private variable so that UI/View can't modify directly
fun getServerTime() {
serverTimeData.value = serverTimeRepo.getServerTime().value // Rather than returning LiveData, we set value to our local MutableLiveData
}
fun observeServerTime(): LiveData<TimeResponse> {
return serverTimeData //Here we expose our MutableLiveData as LiveData to avoid modification from UI/View
}
}
现在,我们在LiveData
外部直接观察到此ClickListener
,我们只是通过按钮点击调用API方法,如下所示:
//Assuming that this code is inside onCreate() of your Activity/Fragment
//first we observe our LiveData
serverTimeViewModel.observeServerTime().observe(this@HomeScreenActivity, Observer {
//In such case, we won't observe multiple LiveData but one
})
//Then during our ClickListener, we just do API method call without any callback.
tvPWStart.setOnClickListener {
serverTimeViewModel.getServerTime()
}