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 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> kotlin协程与rxjava分析理解(一) -> 正文阅读

[移动开发]kotlin协程与rxjava分析理解(一)

什么是协程

  • 处理多任务并发的手段,最大的特点就是可以自动帮助我们切换线程,简单说协程就是一个线程框架
  • developer链接
  • 官网链接

协程和线程的关系

协程和线程,都能用来实现异步调用,但是这两者之间是有本质区别的

  • 协程是编译器级别的,线程是系统级别的。协程的切换是由程序来控制的,线程的切换是由操作系统来控制的
  • 协程是协作式的,线程是抢占式的。协程是由程序来控制什么时候进行切换的,而线程是有操作系统来决定线程之间的切换的。
  • 一个线程可以包含多个协程
  • Java中,多线程可以充分利用多核cpu,协程是在一个线程中执行
  • 协程适合io密集型的程序,多线程适合计算密集型的程序(适用于多核cpu的情况)。当你的程序大部分是文件读写操作或者网络请求操作的时候,这时你应该首选协程而不是多线程,首先这些操作大部分不是利用cpu进行计算而是等待数据的读写,其次因为协程执行效率较高,子程序切换不是线程切换,是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显
  • 使用协程可以顺序调用异步代码,避免回调地狱

协程 VS Rxjava

协程相对RxJava有什么优点呢?

  • RxJava堆栈可读性查,一旦出现问题,堆栈信息爆炸,难以定位问题,而协程就可以避免这个问题
  • 协程用同步的方式写异步的代码,美好了生活,方便代码阅读
  • 协程学习曲线比较平坦,相对于RxJava,协程对初学者更易于学习

RxJava比协程厉害的地方?

  • RxJava真正发力的场景,比如说这时候来个场景加载九张图片,奇数张模糊化,偶数张圆角话,这时候Kotlin协程就无能为力了,因为它只是个异步工具,借助Kotlin的语言优势,处理异步问题如鱼得水。RxJava更多的体现是一种编程思维,你只需要去管做什么,不需要管怎么做。两者的设计理念还是大有不同的

协程和Rxjava一样可以支持多个请求同步或异步处理

  • Rxjava多个请求 并发无序
    • 使用 flatMap 关键字 ,代码示例
        mViewModel.getOrder(uuid).flatMap {
            mViewModel.queryClient(QueryRequest().apply {
                start = 0
                limit = 20
                filters.add(FilterParam("keyword:%=%", it.data?.customerName))
            })
        }.flatMap {
            if (it.data?.size == 0) {
                throw Throwable("这里抛出异常")
            } else {
                setCurClientData(ChooseClientWrapper(it.data?.get(0)))
            }
            mViewModel.queryGoods(QueryRequest().apply {
                filters.add(FilterParam("shopId:=", StorageMgr.getConfig(Constants.PS4_WosShop)))
                filters.add(FilterParam("customerId:=", mViewModel.curClient.get().data?.code))
                filters.add(FilterParam("wrhId:=", mViewModel.curWrh.get().data?.uuid))
                filters.add(FilterParam("skuId:in", arrayListOf<String>().apply {
                    mViewModel.goodsLines.forEach { goodsLine ->
                        add(goodsLine.gdGid.toString())
                    }
                }))
            })
        }
            .doOnSubscribe { showLoading() }
            .doAfterTerminate { hideLoading() }
            .bindLifeCycle(this)
            .subscribe({},{})
  • Rxjava多个请求 同步有序
    • 使用 concatMap 关键字 ,代码示例
    • .map是每个接口成功会触发,.count()是保证所有接口同步走完
 mViewModel.listPictureParam.clear()
        Observable.fromIterable(mViewModel.listPictureCompress).concatMap {
            mViewModel.uploadImage(BOssImage().apply {
                name = FileUtils.getFileNameWithSuffix(it)
                ext = FileUtils.getSuffix(it)
                bytes = Base64.encodeToString(FileUtils.file2byte(it), Base64.DEFAULT)
            }).toObservable()
        }.map {
            mViewModel.listPictureParam.add(it.data?.url)
        }.count().flatMap {
            mViewModel.deliver(RfOrderDeliverReq().apply {
                orderId = mViewModel.uuid.get()
                if (mViewModel.carNumEdit.get() != null) {
                    carNumber = mViewModel.carNumEdit.get().trim()
                }
                if (mViewModel.remarkEdit.get() != null) {
                    remark = mViewModel.remarkEdit.get().trim()
                }
                vouchers.addAll(mViewModel.listPictureParam.map { it })
            })
        }.doOnSubscribe { showLoading() }
            .doAfterTerminate { hideLoading() }
            .bindLifeCycle(this)
            .subscribe({},{})
  • 协程多请求待后续补充

协程如何使用

  • 添加依赖
       // Coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2' 
  • 启动一个协程
CoroutineScope(Dispatchers.Main).launch{
}
  • 挂起函数

这里涉及到2个新东西,第一个是 suspend 修饰符,另一个是 withContext 函数
suspend的作用就是标志方法为挂起函数,被修饰为挂起函数的函数,只能在协程或者其他挂起函数中调用
withContext函数的作用就是用来切换线程,后面可以看到Dispatchers.IO,就是我切换到IO线程了
这样,挂起函数就可以切到其他线程来执行了,执行完又回到launch中的主线程中继续执行,达到了自动切换线程效果

    private suspend fun getData(): String {
        return withContext(Dispatchers.IO) {
            "hen_coder"
        }
    }

后续更新如何把项目中Rxjava请求接口换成协程

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:41:20  更:2022-02-28 15:42:30 
 
开发: 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/24 15:59:09-

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