I want to get request to network every 3 seconds and in the some condition stop it. I am using Coroutine
for network request.I used postDelayed()
method and it work correctly. But I want to make the next request after previous response of the previous request is complete.I used delay
method of Coroutine
but But The UI have freeze and My app is remained in the infinite loop .How to handle this task using postDelayed
or coroutine? I create network request in the this repository:
class ProcessRepository @Inject constructor(private val apiService: ApiService) {
val _networkState = MutableLiveData<NetworkState>()
val _networkState_first = MutableLiveData<NetworkState>()
val completableJob = Job()
private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)
private val brokerProcessResponse = MutableLiveData<BrokerProcessResponse>()
fun repeatRequest(processId:String):MutableLiveData<BrokerProcessResponse>{
var networkState = NetworkState(Status.LOADING, userMessage)
_networkState.postValue(networkState)
coroutineScope.launch {
val request = apiService.repeatRequest(processId, token)
withContext(Dispatchers.Main) {
try {
val response = request.await()
if (response.isSuccessful) {
brokerProcessResponse.postValue(response.body())
var networkState = NetworkState(Status.SUCCESS, userMessage)
_networkState.postValue(networkState)
} else {
var networkState = NetworkState(Status.ERROR, userMessage)
_networkState.postValue(networkState)
}
} catch (e: IOException) {
var networkState = NetworkState(Status.ERROR, userMessage)
_networkState.postValue(networkState)
} catch (e: Throwable) {
var networkState = NetworkState(Status.ERROR, userMessage)
_networkState.postValue(networkState)
}
}
delay(3000) // I only just add this line for try solution using coroutine
}
return brokerProcessResponse
}
And this is code in my fragment:
private fun repeatRequest(){
viewModel.repeatRequest(processId).observe(this, Observer {
if(it!=null){
process=it.process
if(it.process.state== FINDING_BROKER || it.process.state==NONE){
inProgress(true)
}else{
inProgress(false)
}
setState(it!!.process.state!!,it.process)
}
})
}
private fun pullRequest(){
while (isPullRequest){
repeatRequest()
}
}
And My solution using postDelayed
:
private fun init() {
mHandler = Handler()
}
private fun pullRequest() {
mRunnable = Runnable {
repeatRequest()
Log.e(TAG, "in run")
mHandler.postDelayed(
mRunnable,
3000
)
}
mHandler.postDelayed(
mRunnable,
3000
)
}
private fun cancelRequest() {
viewModel.cancelRequest(processId).observe(this, Observer {
if (it != null) {
processShareViewModel.setProcess(it.process)
mHandler.removeCallbacks(mRunnable)
mHandler.removeCallbacksAndMessages(null)
isPullRequest = false
if (findNavController().currentDestination?.id == R.id.requstBrokerFragment) {
val nextAction = RequstBrokerFragmentDirections.actionRequstBrokerFragmentToHomeFragment()
// nextAction.keyprocess = it.process
findNavController().navigate(nextAction)
}
}
Log.e(TAG, "response request borker: " + it.toString())
})
}
override fun onDestroy() {
super.onDestroy()
// Stop the periodic task
isPullRequest = false
mHandler.removeCallbacks(mRunnable)
mHandler.removeCallbacksAndMessages(null)
}