kotlin-coroutine can not be launched

82 views Asked by At

when my fragment go backgroud of system, it invoke onStop().and then when my fragment go front desk of system, it invoke onResume(). but mainViewModelScope does not lanuch a coroutine.

my fragment

    override fun onResume() {
        super.onResume()
        Log.d("aaaa", "resume========")
        viewModel.startFetchDeviceTimer()
    }

    override fun onStop() {
        super.onStop()
        Log.d("aaaa", "stop========")
        viewModel.cancelFetchDeviceTimer()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("aaaa", "destroy========")
    }

my viewModel

    private val mainViewModelScope = CoroutineScope(Dispatchers.Main + SupervisorJob())

    fun startFetchDeviceTimer() {
        startTimerActual()
    }

    private fun startTimerActual() {
         // launchWithVM({
        mainViewModelScope.launch {
            while (isActive) {
                Log.d(TAG, Thread.currentThread().name)
                // 网络请求异步任务在IO线程的协程中
                ioScope.launch {
                    Log.d(TAG, Thread.currentThread().name)
                    val deviceResponse = homeRepository.getDeviceList()
                    val deviceVOList = deviceResponse.deviceList.map { deviceModel ->
                        mapModel2VO(deviceModel)
                    }
                    deviceVOListData.postValue(deviceVOList)
                }
                delay(FETCH_DEVICE_INTERVAL.toDuration(DurationUnit.SECONDS))
            }
        }
        // }, {})
    }

    fun cancelFetchDeviceTimer() {
        if (mainViewModelScope.isActive) {
            mainViewModelScope.cancel()
        }
    }

I want mainViewModelScope to lanuch a coroutine when my fragment go front desk of system. How can i do that?

2

There are 2 answers

1
eta cao On BEST ANSWER
 viewLifecycleOwner.lifecycleScope.launch {
        viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
            viewModel.startFetchDeviceTimer()
        }
    }
3
ninhnau19 On

I tested your code and it work fine. mainViewModelScope will run every time onresume called. In case you cancel mainViewModelScope in onStop(), you could remove it. Please check

viewModel.cancelFetchDeviceTimer()

If you need cancel coroutine when app in background, you can use this way:

var mainViewModelScope: Job? = null

fun startTimerActual() {
   mainViewModelScope = viewModelScope.launch(Dispatchers.Main) {
       //do your job
   }
}

fun cancelFetchDeviceTimer() {
    mainViewModelScope?.cancel()
}