android - 如何在kotlin中使用协程每隔几毫秒调用一个函数

标签 android kotlin coroutine

我想每 3 秒收到一次网络请求,并在某些情况下停止它。我正在使用 Coroutine 进行网络请求。我使用了 postDelayed() 方法并且它工作正常。但是我想在上一个请求的上一个响应完成后发出下一个请求。我使用了 Coroutinedelay 方法但是 UI 已经卡住并且我的应用程序保留在无限循环。如何使用 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
    }

这是我 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()
        }

    }

我的解决方案使用 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()

关于android - 如何在kotlin中使用协程每隔几毫秒调用一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57899613/

相关文章:

android - 在 Android (kotlin) 的 ListView 上向下滚动时发生错误

android - 连接均衡器和低音增强

kotlin - CancellationException何时会发生?

android - 在 OnePlus 6 上显示广告时应用程序崩溃

android - OBDSim 在 Windows 8.1 上通过蓝牙与 Android 设备连接

android - ionic 推送 : GCM project number not found in android application

android - 何时在 Android 中为 ComponentName 使用哪个构造函数?

Kotlin 从父类(super class)中已经存在的接口(interface)实现方法

android - 在Activity/Fragment中,如何获取/等待ViewModel协程操作的返回值?

kotlin - Unresolved reference : async in Kotlin in 1. 3