Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Androidの非同期処理をKotlinコルーチンで行う

yagi
June 12, 2017

 Androidの非同期処理をKotlinコルーチンで行う

yagi

June 12, 2017
Tweet

More Decks by yagi

Other Decks in Technology

Transcript

  1. "OESPJEͷඇಉظॲཧΛ
    ɹɹɹɹɹίϧʔνϯͰߦ͏
    3Y+B/JHIU
    5PTIJIJSP:BHJ

    View full-size slide

  2. ࣗݾ঺հ
    w ീ໦ढ़޿ !TZTZBHJ

    w "OESPJEΤϯδχΞ ٕज़෦௕

    View full-size slide

  3. 3Y+B/JHIUͳͷʹ
    ίϧʔνϯʁ

    View full-size slide

  4. 3Y+BWBͷ༻్
    w -JTUॲཧͷந৅ԽɾετϦʔϜԽ
    w 0QUJPOBM
    w 1SPNJTF
    w %BUB#JOEJOH
    w &WFOU#VT

    View full-size slide

  5. 3Y+BWBͷ༻్
    w -JTUॲཧͷந৅ԽɾετϦʔϜԽ
    w 0QUJPOBM
    w 1SPNJTF
    w %BUB#JOEJOH
    w &WFOU#VT

    View full-size slide

  6. 1SPNJTFͱͯ͠ͷ3Y+BWBΛ
    ίϧʔνϯ BTZODBXBJU

    Ͱஔ͖׵͑ΒΕΔͷͰ͸ʁ

    View full-size slide

  7. ΞδΣϯμ
    w ίϧʔνϯͱ͸ͳʹ͔
    w ,PUMJOʹ͓͚Δίϧʔνϯ
    w ࠓճऔΓѻ͏ඇಉظॲཧͷൣғ
    w 3Y+BWBͰͷ࣮૷
    w ίϧʔνϯͰͷ࣮૷
    w ײ૝

    View full-size slide

  8. ίϧʔνϯͱ͸ͳʹ͔

    View full-size slide

  9. ίϧʔνϯͱ͸ͳʹ͔
    w ίϧʔνϯʢӳDPSPVUJOFʣͱ͸ϓϩάϥϛ
    ϯάͷߏ଄ͷҰछɻαϒϧʔνϯ͕ΤϯτϦʔ͔
    ΒϦλʔϯ·ͰΛҰͭͷॲཧ୯Ґͱ͢Δͷʹର͠ɺ
    ίϧʔνϯ͸͍ͬͨΜॲཧΛதஅͨ͠ޙɺଓ͖͔
    ΒॲཧΛ࠶։Ͱ͖Δ
    w αϒϧʔνϯͱҟͳΓɺঢ়ଶ؅ཧΛҙࣝͤͣʹߦ
    ͑ΔͨΊɺڠௐతॲཧɺΠςϨʔλɺແݶϦετɺ
    ύΠϓͳͲɺܧଓঢ়گΛ࣋ͭϓϩάϥϜ͕༰қʹ
    هड़Ͱ͖Δɻ
    WJB8JLJQFEJBIUUQTKBXJLJQFEJBPSHXJLJ&#&"#&#$&&#

    View full-size slide

  10. ؔ਺ͷ్தͰதஅͨ͠Γ
    ࠶։ͨ͠ΓͰ͖Δ΍ͭ

    View full-size slide

  11. ,PUMJOʹ͓͚Δίϧʔνϯ

    View full-size slide

  12. ,PUMJO͔Βಋೖ
    w ʹϦϦʔε
    w ݴޠ࢓༷ʹʮίϧʔνϯΛ࣮૷͢ΔͨΊ
    ͷػೳʯΛ௥Ճ
    ࢓༷Λٞ࿦͢ΔϦϙδτϦ
    IUUQTHJUIVCDPN,PUMJOLPUMJODPSPVUJOFTCMPCNBTUFSLPUMJODPSPVUJOFTJOGPSNBMNE

    View full-size slide

  13. ࣮ࡍͷػೳ͸ϥΠϒϥϦͱͯ͠ఏڙ
    w DPSF SFBDUJWF VJ JOUFHSBUJPOͳ
    ͲͷϞδϡʔϧʹ෼͔Ε͍ͯΔ
    ίϧʔνϯϥΠϒϥϦͷϦϙδτϦ
    IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFT

    View full-size slide

  14. "OESPJE޲͚ʹ΋ଗ͍ͬͯΔ
    w DPSFͱVJBOESPJEϞδϡʔϧΛ࢖͑͹
    େମ͍͚Δ
    "OESPJEϞδϡʔϧͷ༷ࢠ
    IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTUSFFNBTUFSVJLPUMJOYDPSPVUJOFTBOESPJE

    View full-size slide

  15. ͨͩ͠·ͩFYQFSJNFOUBM
    w LPUMJOYDPSPVUJOFTFYQFSJNFOUBM
    ύοέʔδʹؔ࿈͢ΔΫϥε͕͋Δ
    w ຊ൪౤ೖ͸ͦΕͳΓʹ֮ޛ͕ඞཁ

    View full-size slide

  16. ࠓճऔΓѻ͏ඇಉظॲཧͷൣғ

    View full-size slide

  17. ࠓճऔΓѻ͏ඇಉظॲཧͷൣғ
    w ୯ൃͷ࣮ߦ
    w ௚ྻͷ࣮ߦ
    w ฒྻͷ࣮ߦ
    w ΤϥʔϋϯυϦϯά
    w Ωϟϯηϧ
    ʴ

    View full-size slide

  18. 3Y+BWBͰͷ࣮૷

    View full-size slide

  19. ؀ڥ
    w 3Y"OESPJE
    w 3Y,PUMJO

    View full-size slide

  20. ୯ൃͷ࣮ߦ
    val disposable = shopApi.getShop(10)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
    {
    // success
    },
    {
    // error
    }
    )
    εέδϡʔϥΛ͍͍ײ͡ʹઃఆ

    View full-size slide

  21. ௚ྻͷ࣮ߦ
    val disposable = userApi.me()
    .flatMap { user ->
    subscriptionShopApi.getSubscriptionShops(user.id)
    }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
    {
    // success
    },
    {
    // error
    }
    )
    qBU.BQΛ࢖ͬͯ௚ྻʹ࣮ߦ͢Δ

    View full-size slide

  22. ฒྻͷ࣮ߦ
    val disposable = Single.zip>(
    userApi.me().subscribeOn(Schedulers.io()),
    shopApi.getShop(10L).subscribeOn(Schedulers.io()),
    BiFunction { user, shop ->
    Pair(user, shop)
    }
    )
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
    { (user, shop) ->
    // success
    },
    {
    // error
    }
    )
    [JQΛ࢖ͬͯฒྻʹ࣮ߦ͢Δ

    View full-size slide

  23. Ωϟϯηϧ
    val disposable = shopApi.getShop(10)
    .subscribe(/*ུ*/)
    disposable.dispose()

    View full-size slide

  24. ίϧʔνϯͰͷ࣮૷

    View full-size slide

  25. ؀ڥ
    w ,PUMJO
    w LPUMJOYDPSPVUJOFTDPSF
    w LPUMJOYDPSPVUJOFTBOESPJE

    View full-size slide

  26. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    }

    View full-size slide

  27. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    }
    Ϗϧμʔؔ਺ͱΑ͹ΕΔɺ
    ίϧʔνϯΛߏங͢Δؔ਺

    View full-size slide

  28. MBVODIؔ਺
    w $PSPVUJOF$POUFYUʹ࣮ߦ؀ڥΛࢦఆ͢Δ
    w $PSPVUJOF4UBSU͸࣮ߦ։࢝ͷλΠϛϯάΛࢦఆ͢Δ
    w ୈࡾҾ਺ʹ࣮ߦ͢ΔϒϩοΫΛ౉͢
    w ࣮ߦঢ়ଶΛද͢+PCΛฦ͢
    IUUQTLPUMJOHJUIVCJPLPUMJOYDPSPVUJOFTLPUMJOYDPSPVUJOFTDPSFLPUMJOYDPSPVUJOFTFYQFSJNFOUBMMBVODIIUNM
    fun launch(
    context: CoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
    ): Job

    View full-size slide

  29. MBVODIؔ਺
    val job = launch(UI) {
    //…

    View full-size slide

  30. MBVODIؔ਺
    val job = launch(UI) {
    //…
    LPUMJOYDPSPVUJOFTBOESPJE͕ఏڙ͢Δ$PSPVUJOF$POUFYUɻ
    ౉ͨ͠ϒϩοΫ಺ͷ͢΂ͯͷ࠶։ॲཧΛ6*εϨουͰߦ͏ɻ

    View full-size slide

  31. BTZODؔ਺
    w ୈࡾҾ਺Ͱ࣮ߦ͢ΔϒϩοΫ͕໭Γ஋Λ࣋ͭ
    w ࣮ߦঢ়ଶͱ࣮ߦ݁ՌΛ࣋ͭ%FGFSSFE5Λฦ͢
    IUUQTLPUMJOHJUIVCJPLPUMJOYDPSPVUJOFTLPUMJOYDPSPVUJOFTDPSFLPUMJOYDPSPVUJOFTFYQFSJNFOUBMBTZODIUNM
    fun async(
    context: CoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T
    ): Deferred

    View full-size slide

  32. BTZODؔ਺
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    //…

    View full-size slide

  33. BTZODؔ਺
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    //…
    LPUMJOYDPSPVUJOFTDPSF͕ఏڙ͢Δ$PSPVUJOF$POUFYUɻ
    KBWBVUJMDPODVSSFOU'PSL+PJO1PPMDPNNPO1PPM
    Λ
    ࢖ͬͯεϨουϓʔϧΛ࡞Γɺ࠶։ॲཧΛεϨουͰ࣮ߦ͢Δɻ
    "OESPJE؀ڥ /FYVT9
    Ͱ͸ϓʔϧαΠζ͸ͩͬͨɻ

    View full-size slide

  34. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    }

    View full-size slide

  35. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    } 6*εϨουͰ଴ͪ߹Θ͍͍ͤͯͷ͔ͳʜ

    View full-size slide

  36. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    } %FGFSSFEBXBJU
    ͸தஅؔ਺

    View full-size slide

  37. தஅؔ਺ͱεςʔτϚγϯ
    w ίϯύΠϥ͕தஅؔ਺ͷݺͼग़͠Λঢ়ଶͱͯ͠෼
    ղ͠ɺॲཧશମΛεςʔτϚγϯʹม׵͢Δɻ͜
    ΕʹΑΓɺؔ਺ͷதஅͱ࠶։Λ࣮ݱ͍ͯ͠Δ
    launch(UI) {
    try {
    val shop = async(CommonPool) {…}.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    }
    ঢ়ଶ
    async(CommonPool){…}.await()
    ঢ়ଶ
    val shop =…
    success
    ঢ়ଶ
    error

    View full-size slide

  38. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    }

    View full-size slide

  39. ୯ൃͷ࣮ߦ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch (e: Exception) {
    // error
    }
    }
    ͪΐͬͱ৑௕ͩͳʜ

    View full-size slide

  40. ิॿతͳؔ਺Λ༻ҙ͢Δ
    // async(CommonPool)Λ؆ུԽ͢Δ
    fun async(context: CoroutineContext = CommonPool, start: CoroutineStart
    = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T)
    = kotlinx.coroutines.experimental.async(context, start, block)
    // launch(UI)Λ؆ུԽ͢Δ
    fun ui(start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend
    CoroutineScope.() -> Unit)
    = launch(UI, start, block)

    View full-size slide

  41. ୯ൃͷ࣮ߦ
    val job = ui {
    try {
    val shop = async { shopApi.getShop(10) }.await()
    // success
    } catch (e: Exception) {
    // error
    }
    }

    View full-size slide

  42. ௚ྻͷ࣮ߦ
    val job = ui {
    try {
    val userJob = async { userApi.me() }
    val subscriptionShopsJob = async {
    subscriptionShopApi.getSubscriptionShops(userJob.await().id)
    }
    val subscriptionShops = subscriptionShopsJob.await()
    // success
    } catch (e: Exception) {
    // error
    }
    }

    View full-size slide

  43. ௚ྻͷ࣮ߦ
    val job = ui {
    try {
    val userJob = async { userApi.me() }
    val subscriptionShopsJob = async {
    subscriptionShopApi.getSubscriptionShops(userJob.await().id)
    }
    val subscriptionShops = subscriptionShopsJob.await()
    // success
    } catch (e: Exception) {
    // error
    }
    }
    VTFS+PCͷ݁ՌΛ଴ͪ߹Θͤͨ͋ͱ࣮ߦ

    View full-size slide

  44. ฒྻͷ࣮ߦ
    val job = ui {
    try {
    val userJob = async { userApi.me() }
    val shopJob = async { shopApi.getShop(10L) }
    val user = userJob.await()
    val shop = shopJob.await()
    // success
    catch (e: Exception) {
    // error
    }
    }

    View full-size slide

  45. ฒྻͷ࣮ߦ
    val job = ui {
    try {
    val userJob = async { userApi.me() }
    val shopJob = async { shopApi.getShop(10L) }
    val user = userJob.await()
    val shop = shopJob.await()
    // success
    catch (e: Exception) {
    // error
    }
    }
    $PSPVUJOF4UBSU%&'"6-5Λ࢖͍ͬͯΔͷͰ
    ͦΕͧΕ$PNNPO1PPMͰ௚ͪʹ࣮ߦ͞ΕΔ

    View full-size slide

  46. Ωϟϯηϧ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch(e: CancellationException) {
    // cancel
    } catch (e: Exception) {
    // error
    }
    }
    job.cancel()

    View full-size slide

  47. Ωϟϯηϧ
    val job = launch(UI) {
    try {
    val shop = async(CommonPool) { shopApi.getShop(10) }.await()
    // success!
    } catch(e: CancellationException) {
    // cancel
    } catch (e: Exception) {
    // error
    }
    }
    job.cancel()
    ྫ֎ͱͯ͠ॲཧ

    View full-size slide

  48. ײ૝
    w େମ͍͚Δ ஔ͖׵͑ͯ΋Αͦ͞͏

    w ௚ྻɺฒྻͷ࢖͍෼͚͕؆୯
    w εϨουͷ؅ཧ͕͍ۙ৔ॴʹ͋Δ
    w ΤϥʔɺΩϟϯηϧ͕શͯྫ֎ͳͷͰϋϯυϦϯ
    ά͠΍͍͢
    w ίϧʔνϯ΋3Y+BWBͱಉ͘͡Β͍Ԟ͕ਂ͍ͷͰ
    ͦ͜·Ͱؾܰʹ΍ΔͬͯΘ͚ʹ͸͍͔ͳ͍͚Ͳศ
    རͰ࠷ߴ

    View full-size slide

  49. ࢀߟࢿྉ
    w ࠓճͷίʔυ
    w IUUQTHJUIVCDPNTZTZBHJJNQMFNFOUBUJPOPGBTZODSFRVFTU
    XJUISYKBWBPSDPSPVUJOF
    w $PSPVUJOFTGPS,PUMJO 3FWJTJPO

    w IUUQTHJUIVCDPN,PUMJOLPUMJODPSPVUJOFTCMPCNBTUFSLPUMJO
    DPSPVUJOFTJOGPSNBMNE
    w (VJEFUPLPUMJOYDPSPVUJOFTCZFYBNQMF
    w IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTCMPCNBTUFS
    DPSPVUJOFTHVJEFNE
    w (VJEFUP6*QSPHSBNNJOHXJUIDPSPVUJOFT
    w IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTCMPCNBTUFSVJ
    DPSPVUJOFTHVJEFVJNE

    View full-size slide