Kotlin协程的简单用法(GlobalScope、lifecy

2023-05-08  本文已影响0人  DarcyZhou

"本文转载自:[hudawei996]的Kotlin协程的简单用法(GlobalScope、lifecycleScope、viewModelScope)"

1.协程(Coroutine)

2.GlobalScope(不推荐)

(1)GlobalScope.launch
使用的是DefaultDispatcher,会自动切换到后台线程,不能做UI操作。

 GlobalScope.launch {
            //GlobalScope开启协程:DefaultDispatcher-worker-1
            Log.d(TAG, "GlobalScope开启协程:" + Thread.currentThread().name)
            //子线程中此处不可以做UI操作
            //Toast.makeText(this@MainActivity, "GlobalScope开启协程", Toast.LENGTH_SHORT).show()
           
  }

(2)可以在协程中切换线程

GlobalScope.launch {
            //GlobalScope开启协程:DefaultDispatcher-worker-1
            Log.d(TAG, "GlobalScope开启协程:" + Thread.currentThread().name)
            //子线程中此处不可以做UI操作
            //Toast.makeText(this@MainActivity, "GlobalScope开启协程", Toast.LENGTH_SHORT).show()
            withContext(Dispatchers.Main){
                Toast.makeText(this@MainActivity, "协程中切换线程", Toast.LENGTH_SHORT).show()
            }
        }

(3)GlobalScope.launch(Dispatchers.Main)
通过Dispatchers.Main使协程依托于主线程中,此时可以更新UI等操作。

 GlobalScope.launch(Dispatchers.Main) {
            //GlobalScope开启协程:main
            Log.d(TAG, "GlobalScope开启协程:" + Thread.currentThread().name)
            //可以做UI操作
            Toast.makeText(this@MainActivity, "GlobalScope开启协程", Toast.LENGTH_SHORT).show()
        }

3.lifecycleScope、viewModelScope(推荐)

(1)引入方式

    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'//lifecycleScope
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'//viewModelScope

(2)协程的执行顺序

    private fun test() {
        Log.d(TAG, "test: 方法开始")
        lifecycleScope.launch {
            delay(1000)
            Log.d(TAG, "test: " + Thread.currentThread().name)
            Log.d(TAG, "test: 协程结束")
            Toast.makeText(this@MainActivity, "协程结束", Toast.LENGTH_SHORT).show()
        }
        Log.d(TAG, "test: 方法结束")
    }
D/MainActivity: test: 方法开始
D/MainActivity: test: 方法结束
D/MainActivity: test: main
D/MainActivity: test: 协程结束

(3)协程中多个耗时任务的串行
默认情况下协程中的内容是串行的。

    private fun test2() {
        lifecycleScope.launch {
            val startTime = System.currentTimeMillis()
            val a = getDataA()
            val b = getDataB()
            val sum = a + b
            //D/MainActivity: test2: sum = 3,耗时:3008
            Log.d(TAG, "test2: sum = $sum,耗时:${System.currentTimeMillis() - startTime}")
        }
    }
 
    private suspend fun getDataA(): Int {
        delay(1000)
        return 1
    }
 
    private suspend fun getDataB(): Int {
        delay(2000)
        return 2
    }
D/MainActivity: test2: sum = 3,耗时:3008

(4)协程中多个耗时任务的并行
如果需要并行,例如请求多个接口拿到数据后才能进行操作。

    private fun test3(){
        lifecycleScope.launch {
            val startTime = System.currentTimeMillis()
            val a = lifecycleScope.async { getDataA() }
            val b = lifecycleScope.async { getDataB() }
            val sum = a.await() + b.await()
            //D/MainActivity: test3: sum = 3,耗时:2009
            Log.d(TAG, "test3: sum = $sum,耗时:${System.currentTimeMillis() - startTime}")
        }
    }
    
    private suspend fun getDataA(): Int {
        delay(1000)
        return 1
    }
 
    private suspend fun getDataB(): Int {
        delay(2000)
        return 2
    }
D/MainActivity: test3: sum = 3,耗时:2009

(5)协程的停止
手动停止的情况 job?.cancel()。

    private var job: Job? = null
 
    private fun test4() {
        job = lifecycleScope.launch {
            ...
        }
        job?.cancel()
    }

4.suspend协程挂起原理

上一篇 下一篇

猜你喜欢

热点阅读