$30 off During Our Annual Pro Sale. View Details »

Kotlin Coroutines ことはじめ

M.Inomata
November 30, 2019

Kotlin Coroutines ことはじめ

Kotlin Coroutines の基本や仕組みの話です。
Android での話を中心にしてますが、Kotlinが動く環境ならほぼ同じなので、Android以外のKotlin開発者の方も参考になるかと思います。

2019/11/30 Android 研究&発表会登壇資料
https://arap.connpass.com/event/153097/ #arap_osaka

M.Inomata

November 30, 2019
Tweet

More Decks by M.Inomata

Other Decks in Technology

Transcript

  1. Kotlin Coroutines
    ͜ͱ͸͡Ί

    View Slide

  2. ࣗݾ঺հ

    w ழມॆԝ ͍ͷ·ͨΈͭͻΖ

    w ᷂UFDIWFJO୅දɻ

    J04"OESPJEεϚϗΞϓϦΤϯδχΞɻ

    3Y͕޷͖Ͱ͢ɻ
    w QSJWBUFUXJUUFS!JOP

    View Slide

  3. ࠓ೔ͷ࿩
    • Kotlinίϧʔνϯͷجຊͱ࢓૊ΈΛ஌Ζ͏

    View Slide

  4. ҰൠతʹɺCoroutine ͱ͸
    • தஅɾ࠶։͕Մೳͳαϒϧʔνϯ
    • ฒߦੑ(Concurrent)Λఏڙ͢Δ

    View Slide

  5. αϒϧʔνϯʹී௨ͷؔ਺(ͳͲ)
    αϒϧʔνϯ
    ؔ਺ͳͲ

    ॲཧ
    ॲཧ
    ॲཧ
    ʜ
    SFUVSOl)FMMP 8PSMEl
    ϝΠϯॲཧ
    αϒϧʔνϯ։࢝
    ʜ
    αϒϧʔνϯऴྃ

    View Slide

  6. ίϧʔνϯʹதஅՄೳͳαϒϧʔνϯ
    ίϧʔνϯ
    ॲཧ
    ZJFMElIFMMPz
    ॲཧ
    ZJFMElXPSMEz
    ॲཧ
    ʜ
    ϝΠϯॲཧ
    ίϧʔνϯ։࢝
    ʜ
    ίϧʔνϯऴྃ

    View Slide

  7. ίϧʔνϯ͸
    ฒߦ(Concurrent)ʹಈ࡞͢Δ
    εϨου"
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    εϨου#
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ

    View Slide

  8. ฒߦ(Concurrent) ͱ ฒྻ(Parallel)
    • ฒߦ(Concurrent) ͷྫ: Coroutine
    • ฒྻ(Parallel) ͷྫ: ϚϧνεϨουɾϚϧνϓ
    ϩηε

    View Slide

  9. ฒߦ(Concurrent) != ฒྻ(Parallel)
    εϨου"
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ͜Ε͸ฒߦͰ͋ͬͯ

    ฒྻͰ͸ͳ͍
    ͜Ε͸ฒߦͰ΋

    ฒྻͰ΋͋Δ
    εϨου#
    εϨου"
    ίϧʔνϯ ίϧʔνϯ

    View Slide

  10. Coroutines 

    are 

    light-weight.

    View Slide

  11. Kotlin Coroutines

    View Slide

  12. Kotlin Coroutine ͷΩϞ
    • Suspending Function
    • Structured concurrency
    • CoroutineContext
    • Async as Sync

    View Slide

  13. Kotlin CoroutineͷΩϞᶃ

    Suspending Function

    View Slide

  14. Suspending Function
    • Kotlin Coroutines ͸ɺίϧʔνϯͷதஅͰ͖
    Δੑ࣭Λ suspend ؔ਺(Suspending
    Function)Ͱ࣮ݱ͍ͯ͠Δɻ

    View Slide

  15. Suspending Function ͷੑ࣭
    • suspend ؔ਺͸ଞͷ suspend ؔ਺ͷதͰ͔͠
    ࣮ߦͰ͖ͳ͍ɻ
    • ࢠͷ suspend ؔ਺͕தஅ͢Δͱɺ਌ͷ
    suspend ؔ਺΋ࢭ·Δɻ
    • suspend ؔ਺ͷதͰී௨ͷؔ਺(suspendͰͳ
    ͍ؔ਺)ΛݺͿ͜ͱ͸Ͱ͖Δɻ

    View Slide

  16. Hello world to Kotlin Coroutine

    View Slide

  17. ͜ͷαϯϓϧͰ࢖͍ͬͯΔؔ਺
    • ίϧʔνϯϏϧμʔ(ੜ੒ؔ਺):
    • runBlocking { ... }
    • CoroutineScope#launch { ... }
    • suspendؔ਺:

    delay(timeMillis: Long)
    ※஫: runBlocking͸ཚ༻NGɻ

    ɹɹAndroid؀ڥͰ͸࢖Θͳ͍͜ͱʂ

    View Slide

  18. Android ൛

    View Slide

  19. CoroutineScopeΫϥε
    • ίϧʔνϯͷੜଘظؒΛ؅ཧ͢ΔΦϒδΣΫτɻ
    • MainScope ... UIεϨουͰಈ࡞͢Δείʔϓɻ 

    → AndroidͷActivity ͳͲͱඥ෇͚ͯը໘ͷ

    ɹϥΠϑαΠΫϧͱҰகͤ͞ΒΕΔɻ
    • GlobalScope ... ΞϓϦͷੜଘظؒͱಉ͡είʔϓɻ

    → όονॲཧͳͲɺΞϓϦੜଘதʹऴΘͬͯ͸ࠔΔॲཧΛ࣮ߦ͢Δɻ

    View Slide

  20. αεϖϯυؔ਺ͷྫ
    • delay (timeMillis: Long) 

    ... ࢦఆϛϦඵ଴ͭɻ
    • withTimeout(timeMillis: Long) { ... }
    withTimeoutOrNull(timeMillis: Long) { ...}

    ... ϒϩοΫ಺ͷॲཧ͕ࢦఆϛϦඵΛ௒͑ͨͱ͖ʹ

    ɹλΠϜΞ΢τͤ͞Δɻ
    • yield() 

    ... ॲཧΛॠஅͯ͠ɺ(͋Ε͹)ଞͷίϧʔνϯʹॲཧΛճ͢ɻ

    View Slide

  21. suspend ͸ϊϯϒϩοΩϯά
    • suspend = தஅ
    • ͚ͩͲɺεϨουΛϒϩοΫ͠ͳ͍
    • →εϨουΛϒϩοΫ͢Δྫ: Thread.sleep()

    View Slide

  22. Coroutine ͷ suspend ؔ਺͸ॲཧΛதஅͯ͠ɺ
    ଞͷฒߦॲཧதͷίϧʔνϯʹεϨουΛৡΔɻ
    εϨου"
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ZJFME

    View Slide

  23. εϨου"
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ZJFME

    View Slide

  24. εϨου"
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ZJFME
    ZJFME
    ZJFME

    View Slide

  25. Suspend Function Ͱ
    ίϧʔνϯͷதஅͰ͖Δੑ࣭Λ
    ࣮ݱ͍ͯ͠Δ

    View Slide

  26. Kotlin CoroutineͷΩϞᶄ

    Structured Concurrency

    View Slide

  27. Structured concurrency
    ฒߦੑͷߏ଄Խ
    • ίϧʔνϯ͸਌ࢠؔ܎Λ࣋ͯΔɻ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ ίϧʔνϯ
    ίϧʔνϯ

    View Slide

  28. Α͋͘ΔϚϧνεϨουͳ

    ඇಉظॲཧͷ໰୊
    • Ұ෦ͷεϨουΛམͱͨ͠(མͪͨ)ͱ͖ʹɺ

    ࢒ΓͷεϨουΛڠௐͤ͞Δͷ͕େมɻ
    • λΠϛϯά໰୊ͰσουϩοΫͨ͠Γɺҙਤ͠ͳ
    ͍ڍಈ͕ى͜Γ΍͍͢ɻ
    • ໰୊͕ى͖ͨͱ͖ʹݪҼڀ໌ɾσόοά͕೉͠
    ͍ɻ

    View Slide

  29. ਌ࢠؔ܎ͷ͋Δίϧʔνϯ͸

    ڠௐͤ͞΍͍͢

    View Slide

  30. ਌ࢠؔ܎ͷ͋Δίϧʔνϯ͸

    ڠௐͤ͞΍͍͢
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ ίϧʔνϯ
    ίϧʔνϯ
    ΞΫςΟϒͳ
    ίϧʔνϯ

    View Slide

  31. ਌͸ࢠڙͷऴྃΛ଴ͬͯऴྃ͢Δ
    ΞΫςΟϒͳ
    ίϧʔνϯ
    ଴ػதͷ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ ίϧʔνϯ
    ίϧʔνϯ

    View Slide

  32. ਌ࢠؔ܎ͷ͋Δίϧʔνϯ͸

    ྫ֎ɾΩϟϯηϧ࣌΋ڠௐͤ͞΍͍͢

    View Slide

  33. ਌ࢠؔ܎ͷ͋Δίϧʔνϯ͸

    ྫ֎ɾΩϟϯηϧ࣌΋ڠௐͤ͞΍͍͢
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ ίϧʔνϯ
    ίϧʔνϯ
    ྫ֎ൃੜʂ

    View Slide

  34. ਌ίϧʔνϯʹྫ֎Λ఻೻ͯ͠

    ίϧʔνϯΛऴྃ͢Δ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ ίϧʔνϯ
    ίϧʔνϯ
    ྫ֎ൃੜʂ
    ྫ֎εϩʔ
    ྫ֎εϩʔ

    View Slide

  35. ਌ίϧʔνϯ͕ऴྃ͢Δ࣌͸ɺ

    ࢠίϧʔνϯ΋Ωϟϯηϧ͢Δ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ ίϧʔνϯ
    ίϧʔνϯ
    ྫ֎ൃੜʂ
    KPCDBODFM

    KPCDBODFM

    View Slide

  36. ʹ਌ίϧʔνϯΛࢭΊΕ͹ɺ
    ࢠίϧʔνϯ΋ࢭ·Δ

    View Slide

  37. ਌ࢠϧʔνϯͷείʔϓΛ
    Ωϟϯηϧ͢Ε͹ɺ
    ਌ࢠͱ΋Ͳ΋ࢭΊΒΕΔ

    View Slide

  38. ίϧʔνϯͷ࣮ߦείʔϓΛ

    Ωϟϯηϧ͢Δ͚ͩͰશ෦ࢭΊΒΕΔ
    ίϧʔνϯ
    .BJO4DPQF
    KPCDBODFM

    "DUJWJUZ
    PO%FTUSPZ

    TDPQFDBODFM

    ίϧʔνϯ
    KPCDBODFM

    View Slide

  39. (࠶ܝ) Android Hello world

    View Slide

  40. ίϧʔνϯ͸Ͳ͏΍ͬͯ
    ਌ࢠؔ܎Λ࡞͍ͬͯΔͷ͔ʁ
    → CoroutineScope

    View Slide

  41. launch ͷϥϜμࣜ͸

    this = CoroutineScope

    View Slide

  42. ίϧʔνϯ
    .BJO4DPQF
    KPCDBODFM

    "DUJWJUZ
    PO%FTUSPZ

    TDPQFDBODFM

    ίϧʔνϯ
    ίϧʔνϯ
    KPCDBODFM

    (MPCBM4DPQF
    GlobalScopeͷίϧʔνϯ͸.BJO4DPQFͱؔ܎ͳ͘ಈ͘ʂ
    launch launch
    launch

    View Slide

  43. Structured Concurrency Λ
    ׆༻͢Ε͹
    ίϧʔνϯ؅ཧָ͕ʹͳΔ

    View Slide

  44. Kotlin CoroutineͷΩϞᶅ

    CoroutineContext

    View Slide

  45. CoroutineContext
    %JTQBUDIFSɿ.BJO
    +PCɿͳ͠
    ϝΠϯείʔϓͷίϯςΩετ
    %JTQBUDIFSɿ.BJO
    +PCɿίϧʔνϯ
    είʔϓ1ͷίϯςΩετ
    %JTQBUDIFSɿ.BJO
    +PCɿίϧʔνϯ
    είʔϓͷίϯςΩετ
    %JTQBUDIFSɿ%FGBVMU
    +PCɿίϧʔνϯ
    είʔϓͷίϯςΩετ
    ϝΠϯείʔϓ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ1ͷείʔϓ
    είʔϓ

    ίϧʔνϯͷείʔϓ
    είʔϓ

    ίϧʔνϯ
    ίϧʔνϯͷείʔϓ
    είʔϓ

    View Slide

  46. CoroutineContextͷྫ: Job

    ͋Δίϧʔνϯͷ࣮ߦΛද͢Πϯελϯε
    • ίϧʔνϯΛ࣮ߦ͢ΔͱJobΛ͔͑͢ɻ

    View Slide

  47. CoroutineContext
    %JTQBUDIFSɿ.BJO
    +PCɿͳ͠
    ϝΠϯείʔϓͷίϯςΩετ
    %JTQBUDIFSɿ.BJO
    +PCɿίϧʔνϯ
    είʔϓ1ͷίϯςΩετ
    %JTQBUDIFSɿ.BJO
    +PCɿίϧʔνϯ
    είʔϓͷίϯςΩετ
    %JTQBUDIFSɿ%FGBVMU
    +PCɿίϧʔνϯ
    είʔϓͷίϯςΩετ
    ϝΠϯείʔϓ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ1ͷείʔϓ
    είʔϓ

    ίϧʔνϯͷείʔϓ
    είʔϓ

    ίϧʔνϯ
    ίϧʔνϯͷείʔϓ
    είʔϓ

    View Slide

  48. CoroutineContextͷྫ: CorouttineDispatcher

    ίϧʔνϯΛͲͷεϨουͰಈ͔͔͢ΛܾΊΔਓ
    • Dispatches.Main
    • Dispatchers.Default
    • Dispatchers.IO
    • Dispatchers.Unconfined
    • ͦͷଞ: newSingleThreadContext("threadName")
    ͳͲ

    View Slide

  49. CoroutineContext
    %JTQBUDIFSɿ.BJO
    +PCɿͳ͠
    ϝΠϯείʔϓͷίϯςΩετ
    %JTQBUDIFSɿ.BJO
    +PCɿίϧʔνϯ
    είʔϓ1ͷίϯςΩετ
    %JTQBUDIFSɿ.BJO
    +PCɿίϧʔνϯ
    είʔϓͷίϯςΩετ
    %JTQBUDIFSɿ%FGBVMU
    +PCɿίϧʔνϯ
    είʔϓͷίϯςΩετ
    ϝΠϯείʔϓ
    ίϧʔνϯ
    ίϧʔνϯ
    ίϧʔνϯ1ͷείʔϓ
    είʔϓ

    ίϧʔνϯͷείʔϓ
    είʔϓ

    ίϧʔνϯ
    ίϧʔνϯͷείʔϓ
    είʔϓ

    View Slide

  50. CoroutinenContextͷྫ:ͦͷଞ
    • CoroutineName("name")
    • NonCancellable
    • CoroutineExceptionHandler {}

    View Slide

  51. CoroutineContextͷ࢖͍ํ
    • ίϧʔνϯϏϧμʔͷҾ਺ʹࢦఆͯ͠࢖͏
    • + Ͱ࿈݁ʢॏෳͨ͠ઃఆ͸ӈล༏ઌʣͯ͠૊Έ߹
    Θͤͯ࡞Δ

    View Slide

  52. CoroutineContextͷ࢖͍ํ
    • ಉظతʹৼΔ෣ͬͯ͘ΕΔ withContext ͕ศར

    View Slide

  53. Kotlin CoroutineͷΩϞᶅ

    Async as Sync

    View Slide

  54. TwitterΫϥΠΞϯτతͳ
    ΞϓϦ࣮૷ΛίϧʔνϯͰߟ͑Δɻ
    ϩάΠϯ
    0,
    λΠϜϥΠϯऔಘ
    <
    l͓͸Α͏z
    lࠓ೔͸ษڧձͰ͢z
    >

    View Slide

  55. ίϧʔνϯ͸ඇಉظ
    • ྫ: ϩάΠϯͯ͠λΠϜϥΠϯऔಘ͢ΔAPI࣮૷

    View Slide

  56. ίϧʔνϯ͸ඇಉظʁ
    • ඇಉظॲཧΛಉظతͳײ֮Ͱखଓ͖తʹॻ͚Δ

    View Slide

  57. ίϧʔνϯ͸ඇಉظॲཧΛಉظ
    తʢखଓ͖తʣʹॻ͚Δ
    • ಉظతʹॻ͚ΔͷͰɺ௚ײతͰɺόάΛຒΊࠐΈ
    ʹ͍͘ɻ(σουϩοΫɾ࣮ߦλΠϛϯά໰୊)
    • ͳΜͱ͔Listener΍ίʔϧόοΫ஍ࠈ͔Βͷղ์ɻ

    View Slide

  58. async / await ΋͋Δ
    • async ίϧʔνϯͰɺඇಉظίϧʔνϯʹͭͭ͠ɺ
    ݁ՌΛ଴ͭ͜ͱ΋Ͱ͖Δ
    • async = ݁ՌΛड͚औΕΔػೳΛ΋ͭ launchɻ

    View Slide

  59. Kotlin ίϧʔνϯͷ
    جຊ͸͜Ε͚ͩ

    View Slide

  60. Kotlin Coroutineͷ
    ศརͳػೳͷ঺հ

    View Slide

  61. flow ίϧʔνϯ
    • flow = γʔέϯεͰॱ࣍݁ՌΛྲྀ͢ async.
    • Rx ObservableΛࢀߟʹ࡞ΒΕ͍ͯΔɻ
    • map(transform{}), flatMap,ϑΟϧλ,

    ྫ֎෮ؼॲཧ(catch{}), εϨου੾Γସ͑,
    combineLatest, zip ͳͲ΋͋Δɻ

    View Slide

  62. Channels, produce, actor
    • Channel ͸ίϧʔνϯؒͷ૒ํ޲ͷσʔ
    λ΍ΓऔΓʹ͔ͭ͑ΔΦϒδΣΫτɻ
    • produce { } ... ࢠ͕ૹ৴ͯ͠਌͕ड৴͢Δ
    Ұํ޲νϟϯωϧΛ࡞Δίϧʔνϯɻ
    • actor { } ... ਌͕ૹ৴ͯ͠ࢠ͕ड৴͢ΔҰํ
    ޲νϟωϧΛ࡞Δίϧʔνϯɻ

    View Slide

  63. AndroidXͰ࢖͑Δศརͳػೳ
    • ViewModelScope
    • LifecycleScope
    • liveData { LiveDataScope -> Unit ... }:
    LiveData

    View Slide