kotlin - Coroutine 协程

Posted 清浅岁月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kotlin - Coroutine 协程相关的知识,希望对你有一定的参考价值。

kotlin - Coroutine 协程

协程的创建

kotlin 里没有 new ,自然也不像 JAVA 一样 new Thread,另外 kotlin 里面提供了大量的高阶函数,所以不难猜出协程这里 kotlin 也是有提供专用函数的。kotlin 中 GlobalScope 类提供了几个携程构造函数:

1.launch - 创建协程

2.async - 创建带返回值的协程,返回的是 Deferred 类

3.withContext - 不创建新的协程,在指定协程上运行代码块

4.runBlocking - 不是 GlobalScope 的 API,可以独立使用,区别是 runBlocking 里面的 delay 会阻塞线程,而 launch 创建的不会
kotlin 在 1.3 之后要求协程必须由 CoroutineScope 创建,CoroutineScope 不阻塞当前线程,在后台创建一个新协程,也可以指定协程调度器。比如 CoroutineScope.launch 可以看成 new Coroutine


GlobalScope.launch  
// 创建一个新协程

 delay(1000);// 不阻塞线程
 
        

        async 
// 创建一个新协程
        

        withContext()// 指定一个协程

        runBlocking 
		 	delay(1000); // 阻塞线程
		 
        


第一种:

GlobalScope.launchde 的创建


public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job 
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine


三个参数:

CoroutineContext:

协程上下文,既协程运行的线程,可以使用Dispatchers指定,课可以 自定义使用线程池,Dispatchers也是CoroutineContext的子类,大概类似于android的content。Dispatchers可以指定四种:

Dispatchers.Default

Dispatchers.IO -

Dispatchers.Main - 主线程

Dispatchers.Unconfined - 没指定,就是在当前线程

// 自定义CoroutineContext 使用单线程池
val singleThreadContext = newSingleThreadContext("aa")
GlobalScope.launch(singleThreadContext)


        

CoroutineStart:

协程启动模式,英语基础好的直接看原文,更清楚直接。

DEAFAULT - 模式模式,不写就是默认,立即执行

/**
 * Default -- immediately schedules the coroutine for execution according to its context.
 *
 * If the [CoroutineDispatcher] of the coroutine context returns `true` from [CoroutineDispatcher.isDispatchNeeded]
 * function as most dispatchers do, then the coroutine code is dispatched for execution later, while the code that
 * invoked the coroutine builder continues execution.
 *
 * Note that [Dispatchers.Unconfined] always returns `false` from its [CoroutineDispatcher.isDispatchNeeded]
 * function, so starting a coroutine with [Dispatchers.Unconfined] by [DEFAULT] is the same as using [UNDISPATCHED].
 *
 * If coroutine [Job] is cancelled before it even had a chance to start executing, then it will not start its
 * execution at all, but will complete with an exception.
 *
 * Cancellability of a coroutine at suspension points depends on the particular implementation details of
 * suspending functions. Use [suspendCancellableCoroutine] to implement cancellable suspending functions.
 */

ATOMIC -立即安排执行,但是无法取消,和默认相似

 /**
 * Atomically (i.e., in a non-cancellable way) schedules the coroutine for execution according to its context.
 * This is similar to [DEFAULT], but the coroutine cannot be cancelled before it starts executing.
 *
 * Cancellability of coroutine at suspension points depends on the particular implementation details of
 * suspending functions as in [DEFAULT].
 */

UNDISPATCHED - 立即执行,直到遇到第一个暂停点,与ATOMIC不同点的是必须在同一个线程,这是一个实验性的api,后面 可能会发生变更。

 /**
 * Immediately executes the coroutine until its first suspension point _in the current thread_ as if the
 * coroutine was started using [Dispatchers.Unconfined]. However, when the coroutine is resumed from suspension
 * it is dispatched according to the [CoroutineDispatcher] in its context.
 *
 * This is similar to [ATOMIC] in the sense that coroutine starts executing even if it was already cancelled,
 * but the difference is that it starts executing in the same thread.
 *
 * Cancellability of coroutine at suspension points depends on the particular implementation details of
 * suspending functions as in [DEFAULT].
 *
 * **Note: This is an experimental api.** Execution semantics of coroutines may change in the future when this mode is used.
 */

LAZY - 在需要的时候自己启动

/**
 * Starts the coroutine lazily, only when it is needed.
 *
 * See the documentation for the corresponding coroutine builders for details
 * (like [launch][CoroutineScope.launch] and [async][CoroutineScope.async]).
 *
 * If coroutine [Job] is cancelled before it even had a chance to start executing, then it will not start its
 * execution at all, but will complete with an exception.
 */

CoroutineScope:协程域

block - 闭包方法体,定义协程内需要执行的操作

Job - 协程构建函数的返回值,可以把 Job 看成协程对象本身,协程的操作方法都在 Job 身上了

job.start() - 启动协程,除了 lazy 模式,协程都不需要手动启动

job.join() - 等待协程执行完毕

job.cancel() - 取消一个协程

job.cancelAndJoin() - 等待协程执行完毕然后再取消

lunch与async

async执行可以带回参数,中的挂起只是阻塞当前这个执行的协程,不阻塞其他协程和线程


 val deferred = GlobalScope.async 
           return@async "1111"
        
        val ttr=deferred.await();


runBlocking

runBlocking 和 launch 区别的地方就是 runBlocking 的 delay 方法是可以阻塞当前的线程的,和Thread.sleep() 一样

以上是关于kotlin - Coroutine 协程的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 协程基础Coroutine

Kotlin 协程基础Coroutine

Kotlin 协程基础Coroutine

Android Kotlin协程coroutine

Kotlin 协程单元测试错误:线程“main @coroutine#1 @coroutine#2”中的异常 java.lang.NullPointerException

Kotlin之协程coroutine lifecycleScope 和 viewModelScope源码