Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android Kotlin协程依赖

Android开发Kotlin语言协程的依赖及使用示例

作者:Rocky_ruan

这篇文章主要为大家介绍了Android开发Kotlin语言协程的依赖及使用示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一:协程的依赖

Kotlin 协程提供了一种全新处理并发的方式,你可以在 Android 平台上使用它来简化异步执行的代码。
如果是用于 Android 平台的话,可以只引用以下的 coroutines-android,当中已经包含了 coroutines-core

//协程依赖
 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"

协程优势:

1.轻量:单个线程上可以运行多个协程,协程支持挂起,不会使正在运行的线程阻塞

2.内存泄漏更少:协程支持结构化并发,从而避免了内存泄漏

3.Jetpact集成:Jetpack库都包含提供全面协程的支持的扩展。

如:ViewModelSocpe,LifecycleScope,LiveData

二:协程使用

1.简单使用

//开启协程
    fun runCoroutine() {
        Log.i("SecondActivity", "协程开始执行")
        Log.i("SecondActivity", "thread=${Thread.currentThread().name}")
        CoroutineScope(Dispatchers.IO).launch {
            delay(2000)
            Log.i("SecondActivity", "协程内部")
            Log.i("SecondActivity", "thread11=${Thread.currentThread().name}")

        }
        Log.i("SecondActivity", "协程下面")
    }

结果:
协程开始执行
thread=main
协程下面
协程内部
thread11=DefaultDispatcher-worker-1

CoroutineContext

协程中使用 CoroutineScope(Dispatchers.IO)的Dispatchers.IO 是CoroutineContext的子类实现
CoroutineContext。即协程上下文,包含多种类型的配置参数。Dispatchers.IO 就是 CoroutineContext 这个抽象概念的一种实现,用于指定协程的运行载体,即用于指定协程要运行在哪类线程上

@Suppress("FunctionName")
public fun CoroutineScope(context: CoroutineContext): CoroutineScope =
    ContextScope(if (context[Job] != null) context else context + Job())

Kotlin 协程库提供了四个 Dispatcher 用于指定在哪一类线程中执行协程:

CoroutineScope

CoroutineScope 即 协程作用域,用于对协程进行追踪。如果我们启动了多个协程但是没有一个可以对其进行统一管理的途径的话,就会导致我们的代码臃肿杂乱,甚至发生内存泄露或者任务泄露。为了确保所有的协程都会被追踪,Kotlin 不允许在没有 CoroutineScope 的情况下启动协程。CoroutineScope 可被看作是一个具有超能力的 ExecutorService 的轻量级版本。它能启动协程,同时这个协程还具备上文所说的 suspend 和 resume 的优势

suspend

suspend 是协程中很重的关键字,它用来修饰函数,表示此函数是一个会挂起的函数,并且 挂起函数只有在协程中使用或者被另一个挂起函数调用,可以暂停和进行恢复,什么情况下需要用到挂起函数

suspend只是对函数的一个标识别,它不像inline,refied等关键字一样会对代码造成影响,而是提醒使用者这是一个挂起函数,具体的挂起业务还是需要函数内部自己实现

withContext

withContext是一个挂起函数,表明它只能在协程或者其他suspend函数调用

public suspend fun <T> withContext(
    context: CoroutineContext,
    block: suspend CoroutineScope.() -> T
): T {
}

launch

lauch是最常见的启动一个协程的方法,可以通过GlobalScope.launch开启一个全局生命周期的协程,也可以通过CoroutineScope(CoroutineContext).launch 来开启一个在指定的 CoroutneContext 范围的协程。也可以记录这个Job并通过Job.cancel()随时取消

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
}
val apiService by lazy { RetrofitClient.instance.create() }
  //开启协程
    fun runCoroutine(name: String, password: String, resultListener: (String, String) -> Unit) {
        Log.i("SecondActivity", "协程开始执行")
        Log.i("SecondActivity", "thread=${Thread.currentThread().name}")
        CoroutineScope(Dispatchers.IO).launch {
            Log.i("SecondActivity", "协程内部")
            Log.i("SecondActivity", "thread11=${Thread.currentThread().name}")
            val request = HttpAccountLoginRequest(name, password, null)
            val block :suspend CoroutineScope.()->BaseResult<HttpAccountLoginResponse> ={
                apiService.requestAccountLogin(request,"android","3.5.4")
            }
            var result:BaseResult<HttpAccountLoginResponse> =block()
            if (result.code=="200"&&result.datas!=null){
                withContext(Dispatchers.Main){
                }
            }
        }
        Log.i("SecondActivity", "协程下面")
    }

launch

withContext:

async

什么是 Job ?

Job 翻译作任务,Job 赋予协程可取消,赋予协程以生命周期,赋予协程以结构化并发的能力。其中平常使用中最为重要的是可取消、结构化并发的特点。尤其 在日常 Android 开发过程中,协程配合 Lifecycle 可以做到自动取消。

Job 的生命周期

Job 的生命周期分为 6 种状态,分为 New、Active、Completing、Cancelling、Cancelled、Completed,通常外界会持有 Job 接口会作为引用被协程调用者所持有,Job 接口提供 isActive、isCompleted、isCancelled 3 个变量使外界可以感知 Job 内部的状态,这3个变量和 Job 生命周期的6种状态的对应关系如下图所示

栗子:
 CoroutineScope(Dispatchers.IO).async {
        }
源码:
public fun <T> CoroutineScope.async(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T
): Deferred<T> {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyDeferredCoroutine(newContext, block) else
        DeferredCoroutine<T>(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}
栗子:
CoroutineScope(Dispatchers.IO).launch {
}
源码:
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
}

一种是通过 launch 启动,一种是通过 async 启动,前者会返回一个 Job 类型的对象,后者会返回一个 Deferred 类型的对象

Job的接口定义

Job 顾名思义就是“工作”的意思,每个协程可以想象成是一个工作任务,启动一个协程就是启动一个工作任务,来看看 Job 接口的主要定义:

//Job 也是继承自 Element,所以它本身也是一个协程上下文 context
public interface Job : CoroutineContext.Element {
    //Key对象,如果你看到 context[Job] 的写法, 就知道其实指的是这里的这个伴生对象 Key
    public companion object Key : CoroutineContext.Key<Job> {
        init {
            CoroutineExceptionHandler
        }
    }
    //是否活动状态,必须满足几个条件:该协程已经启动、没有完成、没有被取消
    public val isActive: Boolean
    //是否完成状态
    public val isCompleted: Boolean
    //是否被取消状态
    public val isCancelled: Boolean   
    //启动协程,开始调度。如果已经启动了,则返回false。与线程的Thread.start()挺类似
    public fun start(): Boolean
    //挂起当前正在运行的协程,等待该 Job 执行完成。与线程的Thread.join()挺类似
    public suspend fun join()
    //取消该 Job
    public fun cancel(cause: CancellationException? = null)
    //该 Job 的子 Job
    public val children: Sequence<Job>
}

小知识:

Kotlin空指针检查

在Kotlin里,可以用“?”表示可以为空,也可以用“!!”表示不可以为空。

给变量加上?标识,会通告所有使用该变量的地方,必须给出为空的补救措施。

var info: String? = null
        println(info?.length)  //第一种补救:如果info为null,就不执行后面的.length代码
        println(info!!.length)  //第二种补救:这里如果为null,我自己负责info,会报出空指针,这种处理需慎用
        if (info != null) {   //第三种补救措施,如下这种同java写法
            println(info.length)
        }
      println(info?.length ?: "空数据")  //第四种补救措施,如果真的为null,则改为返回"空数据"

以上就是Android开发Kotlin语言协程的依赖及使用示例的详细内容,更多关于Android Kotlin协程依赖的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文