我刚刚创建了一个应用程序,我的函数getdata()调用每一秒从服务器和updateui()函数获取新的数据将更新UI中的视图。我不使用任何异步任务或协程在我的应用程序中。我想这样做,请告诉我如何才能做到这一点。
这是我的代码...
private fun getdata(){
try {
val api = RetroClient.getApiService()
call = api.myJSON
call!!.enqueue(object : Callback<ProductResponse> {
override fun onResponse(
call: Call<ProductResponse>,
response: Response<ProductResponse>
) {
if (response.isSuccessful) {
productList = response.body()!!.data
for (list in productList) {
if (list.BB.equals("AAA")) {
aProductList.add(list)
}
}
if (recyclerView.adapter != null) {
eAdapter!!.updatedata(aProductList)
}
updateui()
}
}
override fun onFailure(call: Call<ProductResponse>, t: Throwable) {
println("error")
}
})
} catch (ex: Exception) {
} catch (ex: OutOfMemoryError) {
}
Handler().postDelayed({
getdata()
}, 1000)
}
private fun updateui() {
try {
//some code to handel ui
} catch (e: NumberFormatException) {
} catch (e: ArithmeticException) {
} catch (e: NullPointerException) {
} catch (e: Exception) {
}
}
6条答案
按热度按时间afdcj2ne1#
要使用协程每秒运行一个函数:
然而,如果
getData()
只 * 启动 * 一个网络请求,而不等待它完成,这可能不是一个好主意。函数将在它完成后一秒钟被调用,但因为网络请求是异步完成的,它可能被调度得太多。例如,如果网络请求需要5秒,则在第一个请求完成之前,它将启动4次以上!
要解决这个问题,您应该找到一种方法来挂起协程,直到网络请求完成。
这可以通过使用一个 blocking API来完成,然后将
Dispatchers.IO
传递给launch
函数,以确保它在后台线程上完成。或者,您可以使用suspendCoroutine将基于回调的API转换为挂起的api。
更新-生命周期范围
在具有Android生命周期的组件中,您可以使用以下代码来自动重复UI更新:
此程式码需要目前的
androidx.lifecycle:lifecycle-runtime-ktx
相依性。上面关于getData()中的异步、阻塞或挂起代码的注解仍然适用。
mftmpeh82#
不建议每秒钟都访问服务器。如果您需要连续获取数据,请尝试使用套接字。因为有时服务器需要几秒钟以上的时间来响应您的请求。然后,您的所有请求都将在队列中。如果您仍需要尝试使用此方法,请尝试使用套接字。
ufj5ltwl3#
对于那些不熟悉Coroutine的人
在Build.gradle中添加协同程序
创建重复作业
要启动,请执行以下操作:
停止:
3hvapo4f4#
最后我用一个扩展函数完成了如下操作:
那么就叫它:
然后像这样取消它:
vwoqyblh5#
我在MainViewModel内的Kotlin中的解决方案
7uhlpewt6#
我的解决方案是一次性运行一个代码后,检查某个东西是否成功,并定期检查,功能是:
并在此处启动周期性函数(其中action每2秒运行一次),当启用某些内容并运行某些代码时,该函数将自动结束: