Kotlin-coroutine usage

class MediaSelectActivity : BaseActivity() {
    private val videoInfoViewModel by lazy { ViewModelProvider(this).get(VideoInfoViewModel::class.java) }
    private fun initData() {
        videoInfoViewModel.getSystemVideos(contentResolver)
    }
}

class VideoInfoViewModel : ViewModel() {
    val getSystemVideosLiveData: MutableLiveData<List<MediaInfo>> by lazy { MutableLiveData<List<MediaInfo>>() }
    private val model by lazy { VideoInfoModel() }

    fun getSystemVideos(contentResolver: ContentResolver) {
        viewModelScope.launch {
            getSystemVideosLiveData.value = model.getSystemVideos(contentResolver)
        }
    }
}

class VideoInfoModel {
    suspend fun getSystemVideos(contentResolver: ContentResolver) = withContext(Dispatchers.IO) {
        VideoInfoUtils.getSystemVideos(contentResolver)
    }
}

The execution process is outlined as follows:

  1. The application calls the ViewModel layer getSystemVideos function from the View layer MediaSelectActivity on the main thread;

  2. The getSystemVideos function will use the viewModelScope scope launch to create a new coroutine;

  3. The Model layer uses withContext(Dispatchers.IO) to block execution of time-consuming requests on threads reserved for I/O operations;

  4. After the execution of the suspend method is completed, the return value is returned to the calling place of the View layer on the main thread.

1 CoroutineScope specifies the scope of the coroutine

  • CoroutineScope tracks all coroutines it creates using launch or async, and all coroutines must run within a scope;

  • A CoroutineScope manages one or more related coroutines;

  • Unlike schedulers, CoroutineScope does not run coroutines.

1.1 Classification

  • GlobalScope: The scope of the global coroutine. The coroutine started in this scope can run until the application stops running; it will not block the current thread itself, and the started coroutine is equivalent to a daemon thread, which will not prevent the JVM from ending.

  • runBlocking: a top-level function, unlike GlobalScope, it will block the current thread until the execution of all internal coroutines of the same scope ends

  • coroutineScope: used to create an independent coroutine scope, which will not end itself until all started coroutines are completed; the runBlocking method will block the current thread, but coroutineScope will not, but will suspend and release the underlying thread for other Coroutine usage; runBlocking is a normal function, and coroutineScope is a suspending function

  • CoroutineScope: Custom coroutine scope, such as: CoroutineScope(Dispatchers.Main).launch { }

  • lifecycleScope: used in Lifecycle, used by Activity and Fragment

  • viewModelScope: used in ViewModel, a predefined CoroutineScope, included in the KTX extension

2 withContext specifies the thread that executes the coroutine

  • Dispatchers.Main - Run coroutines on the Android main thread

  • Dispatchers.IO - This dispatcher is optimized for performing disk or network I/O outside of the main thread

  • Dispatchers.Default - This dispatcher is optimized for performing CPU-intensive work outside of the main thread

For example: withContext(Dispatchers.IO) creates a block that runs in the IO thread pool.

3 launch Start the coroutine

        Creates a coroutine and dispatches the execution of its function body to the appropriate scheduler.

4 suspend suspend function

  • suspend is used to suspend the execution of the current coroutine and save all local variables

  • resume is used to resume execution of a suspended coroutine from where it was suspended

  • Can only be called from other suspend functions, or by using a coroutine builder such as launch to start a new coroutine

  • The suspend function will not block the thread where it is located, but will suspend the coroutine and resume execution at a specific time

The delay() function under kotlinx.coroutines.Delay is a suspended function modified by suspend, as follows:

public suspend fun delay(time: Long)

        The delay() function is similar to Thread.sleep() in Java, but it is different from pure thread sleep in that the delay() function is non-blocking.

        For example, when CoroutineA running on ThreadA calls the delay(1000L) function to specify a delay of one second before running, ThreadA will turn to execute CoroutineB, and then continue to execute CoroutineA after one second. With Thread.sleep(), the thread can only wait and cannot perform other tasks.

5 common collocations

  • CoroutineScope(Dispatchers.Main).launch { }

  • GlobalScope.launch {}

  • lifecycleScope.launch { }

  • viewModelScope.launch { }

reference

【https://developer.android.com/kotlin/coroutines/coroutines-adv?hl=zh-cn】

【https://www.kotlincn.net/docs/reference/coroutines/coroutine-context-and-dispatchers.html】

【https://juejin.cn/post/6908271959381901325#heading-32】

【https://juejin.cn/post/6953441828100112392】

【https://toutiao.io/posts/vtq5kjj/preview】

Guess you like

Origin blog.csdn.net/Agg_bin/article/details/128900419