IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android 协程基础(一) -> 正文阅读

[移动开发]android 协程基础(一)

背景:上家公司干了三年,开发语言主要用的JAVA和flutter来开发的,新的公司全是kotlin,所以又要把上上家公司用的kotlin要回顾下了,主要还是协程和Jetpack相关。

基础概念

协程

协程并不是一个新的概念,它并不是 Kotlin 发明的。它们已经存在了几十年,并且在 Go 等其他一些编程语言中很受欢迎。

官方的描述是:协程通过将复杂性放入库来简化异步编程。程序的逻辑可以在协程中顺序地表达,而底层库会为我们解决其异步性。该库可以将用户代码的相关部分包装为回调、订阅相关事件、在不同线程(甚至不同机器)上调度执行,而代码则保持如同顺序执行一样简单。

对比其他几种异步编程的方式:线程、回调、Rxjava:

  • 线程 线程的确很好用,也方便用线程池管理,不过线程的上下文切换是消耗性能的,不过这是可以优化的,可以使用CAS或者优化锁抢占等来优化。
  • 回调 一个函数作为参数传递给另一个函数,在处理完后回调用此函数。确实比较好用,但是业务比较复杂,要小心嵌套陷阱和阻塞。
  • Rxjava 这类响应式编程确实很方便,也不存在多层级嵌套。一切皆是流,并且它还是可观察的。一种比较完美的解决方案,学习成本也比较高。

协程:是一种可以挂起和恢复的编程模型,可以让我们异步逻辑同步化,决绝回调地狱。看个小例子:

fun postBean(bean: Bean) {
    launch {
        val token = preparePost()
        val post = submitPost(token, bean)
        processPost(post)
    }
}

suspend fun preparePost(): Token {
    // 发起请求并挂起该协程
    return suspendCoroutine { /* ... */ } 
}

preparePost函数是个挂起函数,是异步的,但是代码逻辑确是同步化的。

挂起和恢复

协程的核心点就是,函数或者一段程序能够挂起,稍后在挂起的位置恢复
协程添加了suspendresume关键字来操作:

  • suspend 挂起 ,用于暂停执行当前协程,并保存所有局部变量
  • resume 用于让暂停的协程从挂起处继续执行

需要注意的是:挂起函数(被suspend修饰的)只能在协程体内或其他挂起函数内调用。

挂起和阻塞

  • 相同点 都是异步操作
  • 区别 挂起是不会占用CPU的,但是会保存状态,在某个时间恢复执行。而阻塞一般是进程等待资源是发生,会占用系统资源。

调度器

所有的协程必须在调度器中运行,即使在主线程也是一样。

Dispatchers.Main

Android上的主线程,用于处理UI交互和一些轻量级任务,eg:调用UI函数、调用suspend函数、更新LiveData。

Dispatchers.IO

非主线程,专为磁盘和网络IO进行了优化,eg:数据库、文件读写、网络请求。

Dispatchers.Default

非主线程,协程开启的默认调度器,专为CPU密集型任务进行了优化,eg:数组排序、JSON解析、复杂逻辑处理、计算处理。

eg:一个简单的调度器上下文切换代码:

 GlobalScope.launch(Dispatchers.IO){
 			//getUser() 是个挂起耗时函数 
            val user = getUser()
            withContext(Dispatchers.Main){
            	//主线程更新UI
                binding.testText.text = user.name
            }
        }

结构化并发-CoroutineScope

一个场景:当某个协程任务丢失,无法追踪,会导致内存、CPU等资源浪费,也行会发送一个网络请求或者缓存读取任务,但是没有接受,这种场景称为任务泄漏。
所以kotlin又加入了结构化并发,跟之前学过的Rxjava定义生命周期也是一样的,其实就是作用域的限定和追踪。

定义协程必须指定起CoroutineScope,它会追踪所有协程,同样它还可以取消它所启动的协程。

public interface CoroutineScope {
    /**
     * The context of this scope.
     * Context is encapsulated by the scope and used for implementation of coroutine builders that are extensions on the scope.
     * Accessing this property in general code is not recommended for any purposes except accessing the [Job] instance for advanced usages.
     *
     * By convention, should contain an instance of a [job][Job] to enforce structured concurrency.
     */
    public val coroutineContext: CoroutineContext
}

官方解释:这个范围的上下文。上下文由范围封装,并用于作为范围扩展的协程构建器的实现。除了在高级用法中访问Job实例外,不建议出于任何目的访问通用代码中的此属性。
按照约定,应该包含一个作业实例来强制结构化并发。

定义新协程的作用域。每个协程构建器(比如launch,
async等)都是CoroutineScope的扩展,并继承它的coroutineContext来自动传播它的所有元素和取消。

获得独立作用域实例的最佳方法是CoroutineScope()和MainScope()工厂函数。可以使用加号操作符将其他上下文元素附加到作用域。
结构化并发规范:
不建议手动实现此接口,建议采用委托实现。按照约定,作用域的上下文应该包含一个作业实例,以通过取消的传播来强制结构化并发原则。

每个协程构建器(如launch, async等)和每个作用域函数(如coroutineScope,
withContext等)都提供了自己的作用域,并将自己的Job实例放入它运行的代码内部块中。按照惯例,它们都要等待它们块中的所有协程完成,然后才能完成它们自己,从而实现结构化并发。
Android使用: Android在所有具有生命周期的实体中都支持协程作用域。

相关API:

  • GlobalScope 生命周期是进程级别的,即使activity和fragment已经销毁,协程依然执行
 GlobalScope.launch {

        }
  • MainScope 在Activity中使用,可以在onDestory(). 中取消协程
 MainScope().launch {

        }
  • viewModelScope 只能在ViewModel中使用,绑定ViewModel的生命周期
//implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1")
 viewModelScope.launch {

        }
  • lifecycleScope 只能在Activity、Fragment中使用,会绑定Activity和Fragment的生命周期
 lifecycleScope.launch {

        }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:52:22  更:2021-08-16 11:53:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:44:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码