使用liveData的Reformation2会在第二次调用api时调用两次,第三次调用三次等等



我有以下改造客户端的实现:

private val retrofitClient: Retrofit.Builder by lazy {
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.HEADERS
val okHttpClient = OkHttpClient.Builder().addNetworkInterceptor(interceptor)
.cookieJar(SessionCookieJar())
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
Retrofit.Builder()
.baseUrl(URLWebConstants.BASE_URL)
.client(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create())
}
val postYotiApiService: PostYotiAPIService by lazy {
retrofitClient.build().create(PostYotiAPIService::class.java)
}
interface PostYotiAPIService {
@POST("*url*")
fun postYoti(): Call<PostYotiResponse>
}

然后我有一个MainActivityRepository类,其中包含调用内容:

class MainActivityRepository() {
val client = RetrofitClient
var postYotiLiveData = MutableLiveData<YotiData?>()
fun postYoti(): MutableLiveData<YotiData?> {
val myCall = client.postYotiApiService.postYoti()
myCall.enqueue(object : Callback<PostYotiResponse> {
override fun onFailure(call: Call<PostYotiResponse>, t: Throwable) {
Log.d("Retrofit", "Something went wrong", t)
}
override fun onResponse(
call: Call<PostYotiResponse>,
response: Response<PostYotiResponse>
) {
if (response.isSuccessful) {
postYotiLiveData.postValue(response.body()!!.data)
} else {
postYotiLiveData.postValue(null)
}
}
})
return postYotiLiveData
}

然后在Fragment的ViewModel中,我调用这样的函数:

val repository = MainActivityRepository()
fun postYoti(): MutableLiveData<YotiData?> {
return repository.postYoti()
}

最后,在我的片段中,我打了这样的电话:

btnYoti.setOnClickListener {
viewModel.postYoti().observe(viewLifecycleOwner, {
println("Hello World")
}
})
}

我第一次打电话时,一切都很好,我没有问题,《你好,世界》只印了一次。我第二次打电话时,Hello world被打印了两次,总共打印了3次。第三次Hello World被打印了3次,当我放置断点时,我可以看到println被命中了3次。每次单击只需进行一次调用。

您正在onClickListener中观察实时数据!这意味着每当你点击该按钮时,一个新的观察者(带有viewLifecycleOwner(将连接到liveData,并在片段的视图运行期间保持活动状态。因此,每次点击都会添加另一个观察者,除非视图被破坏,否则这些观察者永远不会被删除。当没有操作时使用observe(例如,你在onViewCreated中观察实时数据,它总是会收到任何更改的通知(,在操作时(如点击(只需获取LiveData的值并用它做点什么

override fun onViewCreated(){
//...
btnYoti.setOnClickListener {
viewModel.postYoti()
}
//Add a getter to your VM to prevent direct access to rep

viewModel.repository.postYotiLiveData.observe(viewLifecycleOwner, {
println("Hello World")
}
}
}

另一方面,您可以使用LiveEvent来防止由于恢复片段而导致的冗余打印

最新更新