mar*_*yam 3 android coroutine kotlin
我想每 3 秒收到一次网络请求,并在某些情况下停止它。我正在用于Coroutine网络请求。我使用了postDelayed()方法并且它工作正常。但我想在上一个请求的上一个响应完成后发出下一个请求。我使用了但 UI 已冻结delay的方法Coroutine,并且我的应用程序仍处于无限循环中。如何使用postDelayed协程处理此任务?我在此存储库中创建网络请求:
     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
    }
这是我的片段中的代码:
     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()
        }
    }
我的解决方案使用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)
    }
对于那些刚接触协程的人
在 Build.gradle 中添加协程
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
添加重复作业
    /**
     * start Job
     * val job = startRepeatingJob()
     * cancels the job and waits for its completion
     * job.cancelAndJoin()
     * Params
     * timeInterval: time milliSeconds 
     */
    private fun startRepeatingJob(timeInterval: Long): Job {
        return CoroutineScope(Dispatchers.Default).launch {
            while (NonCancellable.isActive) {
                // add your task here
                doSomething()
                delay(timeInterval)
            }
        }
    }
开始:
  Job myJob = startRepeatingJob(1000L)
停止:
    myJob .cancel()
你的 UI 冻结了,因为你的while循环正在不间断地运行:
while (isPullRequest){
     repeatRequest()
}
您正在异步启动一个协程repeatRequest并在那里调用delay。这不会暂停该pullRequest功能。
您应该在协程(函数)内运行循环repeatRequest。然后,您可以job将此协程的对象提供给调用者,并cancel在您想停止循环时调用:
fun repeatRequest(): Job {
    return coroutineScope.launch {  
        while(isActive) {
            //do your request
            delay(3000)
        }
    }
}
//start the loop
val repeatJob = repeatRequest()
//Cancel the loop
repeatJob.cancel()
| 归档时间: | 
 | 
| 查看次数: | 8156 次 | 
| 最近记录: |