bennyhuo / Bennyhuo

bennyhuo.vercel.app
9 stars 3 forks source link

破解 Kotlin 协程 - 入门篇 | Bennyhuo #15

Open bennyhuo opened 5 years ago

bennyhuo commented 5 years ago

https://www.bennyhuo.com/2019/04/01/basic-coroutines/

假定你对协程(Coroutine)一点儿都不了解。通过阅读本文看看是否能让你明白协程是怎么一回事。1. 引子我之前写过一些协程的文章,很久以前了。那会儿还是很痛苦的,毕竟 kotlinx.coroutines 这样强大的框架还在襁褓当中,于是乎我写的几篇协程的文章几乎就是在告诉大家如何写这样一个框架——那种感觉简直糟糕透了,因为没有几个人会有这样的需求。这次准备从协程用户(也就是程序员你我他啦)的

tangtingyun commented 5 years ago

哈哈 多谢分享 坚持写博客真实厉害 今天刚好也在看协程网络请求

bennyhuo commented 5 years ago

@tangtingyun 哈哈 多谢分享 坚持写博客真实厉害 今天刚好也在看协程网络请求

好的 有问题多交流

lemoeo commented 5 years ago

你好,请问我这种方式为何报错: java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #5)

@GET("v3/weather/now.json")
    suspend fun getWeather2(@Query("key") key: String, @Query("location") location: String,
                            @Query("language") language: String, @Query("unit") unit: String) : Weather

GlobalScope.launch(Dispatchers.Main) {     
          val weather = testService.getWeather2("***************", "beijing", "zh-Hans", "c")
}
bennyhuo commented 5 years ago

@ikarr 你好,请问我这种方式为何报错: java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #5)

@GET("v3/weather/now.json")
    suspend fun getWeather2(@Query("key") key: String, @Query("location") location: String,
                            @Query("language") language: String, @Query("unit") unit: String) : Weather

GlobalScope.launch(Dispatchers.Main) {     
          val weather = testService.getWeather2("***************", "beijing", "zh-Hans", "c")
}

Retrofit 2.5.0 还不支持 suspend,用 2.5.1 以上的(还没发布,可以用源码编译)

richardissuperman commented 5 years ago

想问一下博主,您觉得Coroutine和RxJava比到底有什么优势呢,现在我觉得除了代码看上去简洁一些之外没发现有什么本质区别。谢谢!

bennyhuo commented 5 years ago

@richardissuperman 想问一下博主,您觉得Coroutine和RxJava比到底有什么优势呢,现在我觉得除了代码看上去简洁一些之外没发现有什么本质区别。谢谢!

这里提到的是比较接近的使用场景。RxJava 是 monad,Kotlin 的协程是 cps,这是二者本质的区别,从外观上,RxJava 的代码仍然是异步的,kotlin协程的是同步的(至少看起来是)。RxJava 的优势是 Java 也可以用,Coroutine 的优势是,你可以写出更灵活易懂的代码。

dokinkon commented 5 years ago

從開始學習Coroutine到現在,看到最好的教學文!謝謝分享

bennyhuo commented 5 years ago

@dokinkon 從開始學習Coroutine到現在,看到最好的教學文!謝謝分享

加油,有问题直接留言~

simonjava commented 5 years ago

在有很多网络io的情况下,使用协程会比 rxjava 性能更好么?

bennyhuo commented 5 years ago

@simonjava 在线程复用层面确实有优势。如果是客户端程序,其实协程能带来的更多的是开发体验的提升。

humanheima commented 5 years ago

还是不知道协程是什么,太抽象了

bennyhuo commented 5 years ago

@humanheima 还是不知道协程是什么,太抽象了

其实就是一个可以挂起、可以从挂起的位置恢复执行的一个任务,或者一段程序,一个函数。

limin05030 commented 5 years ago

你好,我有个疑问就是既然协程已经是异步的了,那启动协程的时候指定线程还有什么意义呐?比如我有个异步操作的时候用launch(Dispatchers.Main){}和launch(Dispatchers.IO){}有什么区别?

bennyhuo commented 5 years ago

@limin05030 单线程也可以异步,多线程可以并发异步。

RubiTree commented 4 years ago

大佬问下 为什么说 「suspend 函数是 Kotlin 编译器对协程支持的唯一的黑魔法」呢,上面刚讲的 await 函数不是嘛?

RubiTree commented 4 years ago

我理解到目前这篇文章为止是不是还不需要用到真正协程的概念?只需要一个叫「协程」的线程切换语法糖是吧

bennyhuo commented 4 years ago

await 就是基于 suspend 实现的

--------------原始邮件-------------- 发件人:"RubiTree "<notifications@github.com>; 发送时间:2020年3月28日(星期六) 晚上6:37 收件人:"enbandari/Bennyhuo" <Bennyhuo@noreply.github.com>; 抄送:"Bennyhuo "<bennyhuo@kotliner.cn>;"Author "<author@noreply.github.com>; 主题:Re: [enbandari/Bennyhuo] 破解 Kotlin 协程 - 入门篇 | Bennyhuo (#15)

大佬问下 为什么说 「suspend 函数是 Kotlin 编译器对协程支持的唯一的黑魔法」呢,上面刚讲的 await 函数不是嘛?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

aplixy commented 4 years ago

大哥您的入门教程一上来就讲源码呀😭Future是啥呀

bennyhuo commented 4 years ago

正常啊,协程就好比大学课程,入门也得是微积分了呀。Future都不知道的话那。。。。先google一下补补基础?

--------------原始邮件-------------- 发件人:"xinyuli "<notifications@github.com>; 发送时间:2020年7月10日(星期五) 中午11:41 收件人:"enbandari/Bennyhuo" <Bennyhuo@noreply.github.com>; 抄送:"Bennyhuo "<bennyhuo@kotliner.cn>;"Author "<author@noreply.github.com>; 主题:Re: [enbandari/Bennyhuo] 破解 Kotlin 协程 - 入门篇 | Bennyhuo (#15)

大哥您的入门教程一上来就讲源码呀Future是啥呀

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

aplixy commented 4 years ago

@enbandari 正常啊,协程就好比大学课程,入门也得是微积分了呀。Future都不知道的话那。。。。先google一下补补基础?

--------------原始邮件-------------- 发件人:"xinyuli "<notifications@github.com>; 发送时间:2020年7月10日(星期五) 中午11:41 收件人:"enbandari/Bennyhuo" <Bennyhuo@noreply.github.com>; 抄送:"Bennyhuo "<bennyhuo@kotliner.cn>;"Author "<author@noreply.github.com>; 主题:Re: [enbandari/Bennyhuo] 破解 Kotlin 协程 - 入门篇 | Bennyhuo (#15)

大哥您的入门教程一上来就讲源码呀Future是啥呀

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

嗯嗯,感谢您的教程,我的基础还是有点差了

bennyhuo commented 4 years ago

加油~

--------------原始邮件-------------- 发件人:"xinyuli "<notifications@github.com>; 发送时间:2020年7月10日(星期五) 中午12:20 收件人:"enbandari/Bennyhuo" <Bennyhuo@noreply.github.com>; 抄送:"Bennyhuo "<bennyhuo@kotliner.cn>;"Mention "<mention@noreply.github.com>; 主题:Re: [enbandari/Bennyhuo] 破解 Kotlin 协程 - 入门篇 | Bennyhuo (#15)

@enbandari 正常啊,协程就好比大学课程,入门也得是微积分了呀。Future都不知道的话那。。。。先google一下补补基础?

--------------原始邮件-------------- 发件人:"xinyuli "<notifications@github.com>; 发送时间:2020年7月10日(星期五) 中午11:41 收件人:"enbandari/Bennyhuo" <Bennyhuo@noreply.github.com>; 抄送:"Bennyhuo "<bennyhuo@kotliner.cn>;"Author "<author@noreply.github.com>; 主题:Re: [enbandari/Bennyhuo] 破解 Kotlin 协程 - 入门篇 | Bennyhuo (#15)

大哥您的入门教程一上来就讲源码呀Future是啥呀

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

嗯嗯,感谢您的教程,我的基础还是有点差了

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

zilchzz commented 4 years ago

多谢! 你这个系列真的挺难吃透的,我这已经是看第N遍了,主要原因也是因为 Kotlin 协程本身就比较难懂。 找了那么教程,看来看去也还是你这个系列讲得最好最详细,就算吃不透也能让我在面对协程的时候不再恐惧。 如今协程已经到了1.3.9了,如果能出一系列协程的视频,将协程再由浅入深讲解下的话就好了。

bennyhuo commented 4 years ago

多谢! 你这个系列真的挺难吃透的,我这已经是看第N遍了,主要原因也是因为 Kotlin 协程本身就比较难懂。 找了那么教程,看来看去也还是你这个系列讲得最好最详细,就算吃不透也能让我在面对协程的时候不再恐惧。 如今协程已经到了1.3.9了,如果能出一系列协程的视频,将协程再由浅入深讲解下的话就好了。

我写了一本协程的书,可以参考下:https://item.jd.com/12898592.html

书的内容有部分源自于博客,不过相比博客扩展了非常多的内容,仔细读起来内容的衔接肯定比博客要好一些。

至于视频,协程的部分我在Kotlin 入门到精通 课程里面大概讲了4个小时,有兴趣也可以了解下,视频的内容比书早了大概 2 个月,内容重合度比较高,但书更系统。

zilchzz commented 3 years ago

@enbandari

多谢! 你这个系列真的挺难吃透的,我这已经是看第N遍了,主要原因也是因为 Kotlin 协程本身就比较难懂。 找了那么教程,看来看去也还是你这个系列讲得最好最详细,就算吃不透也能让我在面对协程的时候不再恐惧。 如今协程已经到了1.3.9了,如果能出一系列协程的视频,将协程再由浅入深讲解下的话就好了。

我写了一本协程的书,可以参考下:https://item.jd.com/12898592.html

书的内容有部分源自于博客,不过相比博客扩展了非常多的内容,仔细读起来内容的衔接肯定比博客要好一些。

至于视频,协程的部分我在Kotlin 入门到精通 课程里面大概讲了4个小时,有兴趣也可以了解下,视频的内容比书早了大概 2 个月,内容重合度比较高,但书更系统。

书已经买了在读。 这几天碰到一个疑问一直难以得解,烦请予以解惑。 在分析suspend fun main() 方法时,发现它其实一样会调用到block.startCoroutine,只不过completion是一个RunSuspend。 我有疑问的地方在此: 使用

suspend {
        suspendFunc02("Hello", "Coroutine")
    }.startCoroutine(object : Continuation<Int> {
        override val context: CoroutineContext
            get() = LogInterceptor()

        override fun resumeWith(result: Result<Int>) {
            println("Coroutine End:$result")
        }
    })

以及runSuspend方法时都会调用到startCoroutine方法,而且都是以(suspend()->T)为receiver。但是为什么runSuspend中调用到IntrinsicsJvm#createCoroutineUnintercepted时,(this is BaseContinuationImpl)为false,而普通的startCoroutine却是true,从而导致了普通的suspend()->T会编译成SuspendLambda,而suspend main则是RestrictedContinuationImpl呢? 书写的很好,多谢!!

bennyhuo commented 3 years ago

@enbandari

多谢! 你这个系列真的挺难吃透的,我这已经是看第N遍了,主要原因也是因为 Kotlin 协程本身就比较难懂。 找了那么教程,看来看去也还是你这个系列讲得最好最详细,就算吃不透也能让我在面对协程的时候不再恐惧。 如今协程已经到了1.3.9了,如果能出一系列协程的视频,将协程再由浅入深讲解下的话就好了。

我写了一本协程的书,可以参考下:https://item.jd.com/12898592.html 书的内容有部分源自于博客,不过相比博客扩展了非常多的内容,仔细读起来内容的衔接肯定比博客要好一些。 至于视频,协程的部分我在Kotlin 入门到精通 课程里面大概讲了4个小时,有兴趣也可以了解下,视频的内容比书早了大概 2 个月,内容重合度比较高,但书更系统。

书已经买了在读。 这几天碰到一个疑问一直难以得解,烦请予以解惑。 在分析suspend fun main() 方法时,发现它其实一样会调用到block.startCoroutine,只不过completion是一个RunSuspend。 我有疑问的地方在此: 使用

suspend {
        suspendFunc02("Hello", "Coroutine")
    }.startCoroutine(object : Continuation<Int> {
        override val context: CoroutineContext
            get() = LogInterceptor()

        override fun resumeWith(result: Result<Int>) {
            println("Coroutine End:$result")
        }
    })

以及runSuspend方法时都会调用到startCoroutine方法,而且都是以(suspend()->T)为receiver。但是为什么runSuspend中调用到IntrinsicsJvm#createCoroutineUnintercepted时,(this is BaseContinuationImpl)为false,而普通的startCoroutine却是true,从而导致了普通的suspend()->T会编译成SuspendLambda,而suspend main则是RestrictedContinuationImpl呢? 书写的很好,多谢!!

suspend fun main 函数会把作为 startCoroutine 的 receiver 的 block 编译成 Lambda 类型的子类,自然就不是 BaseContinuationImpl 的子类了。看了下 RestrictedContinuationImpl 就是强制上下文为空,其实 suspend main 本来就是设计如此,很容易理解。

而普通的startCoroutine却是true,从而导致了普通的suspend()->T会编译成SuspendLambda,

其他情况下会编译成 SuspendLambda,才会使得 this is BaseContinuationImpl 为 true。这个“导致了” 显然是不对的。

docwei2050 commented 3 years ago

第二次看这个,好亲切

bennyhuo commented 3 years ago

第二次看这个,好亲切

哈哈,好几年了都