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

Androidと非同期処理 とCoroutine1.0.0

yagi
December 18, 2018

Androidと非同期処理 とCoroutine1.0.0

- Kotlin1.3とCoroutine1.0.0とJetpack
- なぜAndroidでコルーチンを使いたいか
- Androidでコルーチンを使う準備
- 並行処理を書く(直列、並列、スコープと例外)
- おまけ1: Rx with Coroutine
- おまけ2: Jetpack with Coroutine

yagi

December 18, 2018
Tweet

More Decks by yagi

Other Decks in Programming

Transcript

  1. ©2018 Lang-8 Inc. ALL Rights Reserved. w ,PUMJOͱ$PSPVUJOFͱ+FUQBDL w ͳͥ"OESPJEͰίϧʔνϯΛ࢖͍͍͔ͨ

    w "OESPJEͰίϧʔνϯΛ࢖͏४උ w ฒߦॲཧΛॻ͘ ௚ྻɺฒྻɺείʔϓͱྫ֎  w ͓·͚3YXJUI$PSPVUJOF w ͓·͚+FUQBDLXJUI$PSPVUJOF ࠓ೔࿩͢͜ͱ
  2. ©2018 Lang-8 Inc. ALL Rights Reserved. ,PUMJO w$PSPVUJOF 4UBCMF 

    w,PUMJO/BUJWF#FUB w,UPS#FUB wΠϯϥΠϯΫϥεɺίϯτϥΫτɺXIFO ࣜͷαϒδΣΫτFUDʜ
  3. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF w$PSPVUJOF4DPQFΛಋೖ͠طଘͷॻ͖ํ͕ EFQSFDBUFEʹ d

     w%JTQBUDIFSTΛಋೖ d  wείʔϓͷྫ֎ͷ࢓༷͕มΘͬͨ d  wFYQFSJNFOUBMQBDLBHFΛഇࢭ d IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTSFMFBTFT
  4. ©2018 Lang-8 Inc. ALL Rights Reserved. w7JFXͷJOqBUF NFBTVSF MBZPVU Ϩϯ

    μϦϯάɺλονΠϕϯτͳͲදࣔʹؔΘΔ ॲཧΛ͢Δ w)[ͳΒϑϨʔϜNT͔͠ͳ͍ ϑϨʔ Ϝམͪ͸ମݧΛଛͶΔ  w௕࣌ؒͷϒϩοΩϯά͸"/3ʹͳΔ "OESPJEͱ6*εϨου
  5. ©2018 Lang-8 Inc. ALL Rights Reserved. w$36% w%BUBCBTFɺ'JMF*0 w4ZOD w/FUXPSL*0

    w$PNQVUF wෳࡶͳܭࢉ ΄ͱΜͲͷΞϓϦ͕ߦ͏ॏ͍ͨॲཧ
  6. ©2018 Lang-8 Inc. ALL Rights Reserved. w"TZOD5BTL w&YFDVUPST ͔ͳΓ௿ϨΠϠʔ 

    w-PBEFST ݱࡏ͸ഇࢭ  w'VUVSF NJO4EL7FSTJPOҎ্  w-JCSBSJFT 3Y+BWBɺ࣮࣭σϑΝΫτελϯμʔυ "OESPJEͷඇಉظॲཧ
  7. ©2018 Lang-8 Inc. ALL Rights Reserved. ίϧʔνϯͷ࣮ߦΠϝʔδ 5ISFBE1PPM 8PSLFS 8PSLFS

    8PSLFS 8PSLFS $PSPVUJOF ʜ ʜ εϨου .#d.#΄ ͲϝϞϦΛ࢖͏ ͭͷίϧʔν ϯͰ,#΄Ͳɻ εϨουͰෳ ਺࣮ߦ͢Δɻ
  8. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜͱ͸ fun getProfile(id: Int,

    f: (Profile) -> Unit) fun loadProfile(id: Int) { getProfile(token) { profile -> showProfile(profile) } }
  9. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜͱ͸ fun getProfile(id: Int,

    f: (Profile) -> Unit) fun loadProfile(id: Int) { getProfile(token) { profile -> showProfile(profile) } } "1*ʹϦΫΤετͯ݁͠ՌΛฦؔ͢਺
  10. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜͱ͸ fun getProfile(id: Int,

    f: (Profile) -> Unit) fun loadProfile(id: Int) { getProfile(token) { profile -> showProfile(profile) } } ׬ྃ࣌ͷίʔϧόοΫΛҾ਺ʹऔΔ
  11. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜͱ͸ fun getProfile(id: Int,

    f: (Profile) -> Unit) fun loadProfile(id: Int) { getProfile(token) { profile -> showProfile(profile) } } ίʔϧόοΫʹଓ͖ͷॲཧΛॻ͘
  12. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜͱ͸ fun getProfile(id: Int,

    f: (Profile) -> Unit) fun loadProfile(id: Int) { getProfile(token) { profile -> showProfile(profile) } } ίʔϧόοΫʹଓ͖ͷॲཧΛॻ͘ ܧଓঢ়گΛ࣋ͭϓϩάϥϜ
  13. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜΛ༰қʹهड़͢Δ suspend fun getProfile(id:

    Int): Profile suspend fun loadProfile(id: Int) { val profile = getProfile(token) showProfile(profile) }
  14. ©2018 Lang-8 Inc. ALL Rights Reserved. ܧଓঢ়گΛ࣋ͭϓϩάϥϜΛ༰қʹهड़͢Δ suspend fun getProfile(id:

    Int): Profile suspend fun loadProfile(id: Int) { val profile = getProfile(token) showProfile(profile) } ϫʔΧʔεϨουͰಈ࡞ 6*εϨουͰಈ࡞
  15. ©2018 Lang-8 Inc. ALL Rights Reserved. ίϧʔνϯ͸ϥΠϒϥϦͰఏڙ͞Ε͍ͯΔ IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFT dependencies {

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1' implementation ‘org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.0.1' }
  16. ©2018 Lang-8 Inc. ALL Rights Reserved. ίϧʔνϯ͸ϥΠϒϥϦͰఏڙ͞Ε͍ͯΔ dependencies { implementation

    'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1' implementation ‘org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.0.1' } wKBS,# wBQL,# wPQUJNJ[F࠷খ,#
  17. ©2018 Lang-8 Inc. ALL Rights Reserved. ͳͥίϧʔνϯΛ࢖͍͍͔ͨ wݶΒΕͨϦιʔεͰεέʔϧͰ͖Δ w εϨουd.#ʹରͯ͠ɺίϧʔνϯ͸,#ఔ౓

    w؆୯ʹ࢖͑Δ ಡΈॻ͖ͷ͠΍͢͞  wܰྔͳϥΠϒϥϦ w KBS,# BQL,# PQUJNJ[F࠷খ,#
  18. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job
  19. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job public interface CoroutineScope { public val coroutineContext: CoroutineContext }
  20. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job
  21. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job
  22. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job ࣮ߦ؀ڥΛઃఆ͢Δ
  23. ©2018 Lang-8 Inc. ALL Rights Reserved. %JTQBUDIFST*0 w*0ʹ࠷దԽͨ͠εϨουϓʔϧ w࠷௿ฒߦ w%FGBVMUͱεϨουϓʔϧͱڞ༗͍ͯ͠

    ΔͷͰߴ଎ Β͍͠ˣ IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTCMPCNBTUFSDPSFLPUMJOYDPSPVUJOFTDPSFTSDTDIFEVMJOH$PSPVUJOF4DIFEVMFSLU
  24. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job
  25. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job ࢠίϧʔνϯͷϋϯυϥ
  26. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onResume() { super.onResume() launch { var count = 0 while (true) { delay(1000) println("hi! ${count++}") } } }
  27. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onResume() { super.onResume() launch { var count = 0 while (true) { delay(1000) println("hi! ${count++}") } } } ίϧʔνϯΛىಈ
  28. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onResume() { super.onResume() launch { var count = 0 while (true) { delay(1000) println("hi! ${count++}") } } } NTఀࢭͯ͠࠶։͢Δ
  29. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onResume() { super.onResume() launch { var count = 0 while (true) { delay(1000) println("hi! ${count++}") } } }
  30. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ override fun onPause()

    { job.cancelChildren() super.onPause() } ࢠίϧʔνϯΛ͢΂ͯ Ωϟϯηϧ ऴྃ ͢Δ
  31. ©2018 Lang-8 Inc. ALL Rights Reserved. $PSPVUJOF4DPQFΛ࣮૷͢Δ class MainActivity :

    AppCompatActivity(), CoroutineScope { val job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onResume() { super.onResume() launch {/*…*/} } override fun onPause() { job.cancelChildren() super.onPause() } }
  32. ©2018 Lang-8 Inc. ALL Rights Reserved. TVTQFOEؔ਺ͱ͸ wεϨουΛϒϩοΩϯά͢Δ͜ͱͳ͘ॲཧΛఀ ࢭͰ͖Δؔ਺ wίʔϧόοΫͷΑ͏ʹ͋ͱͰఀࢭҐஔ͔Β࠶։

    Ͱ͖Δ wTVTQFOEؔ਺͸ଞͷTVTQFOEؔ਺͔ΒͷΈ ݺͼग़͕͠Ͱ͖Δ wίϧʔνϯϏϧμʔʹΘͨ͢ϥϜμࣜ͸ TVTQFOEϥϜμʹͳ͍ͬͯΔɻ
  33. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } }
  34. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ͜͜ͰॲཧΛதஅ͠ɺ࠶։࣌ʹ1SPpMFΛฦؔ͢਺
  35. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ίϧʔνϯͷ࣮ߦ؀ڥΛ੾Γସ͑ΔTVTVQFOEؔ਺
  36. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ίϧʔνϯͷ࣮ߦ؀ڥΛ੾Γସ͑ΔTVTVQFOEؔ਺ ͜͜Ͱ͸ϫʔΧʔεϨουͰಈ͘ઃఆΛ͍ͯ͠Δ
  37. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } "1*ϦΫΤετɻϒϩοΩϯά͢Δॲཧ
  38. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ίϧʔνϯΛىಈ %JTQBUDIFST.BJO KPCͱ͢Δ
  39. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } }
  40. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ
  41. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ ϫʔΧʔεϨουͰಈ࡞
  42. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ ϫʔΧʔεϨουͰಈ࡞ ᶄ࠶։ͯ͠୅ೖ
  43. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ ϫʔΧʔεϨουͰಈ࡞ ᶄ࠶։ͯ͠୅ೖ 6*εϨουͰಈ࡞
  44. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ ϫʔΧʔεϨουͰಈ࡞ ᶄ࠶։ͯ͠୅ೖ 6*εϨουͰಈ࡞ ᶅ7JFXʹ൓ө
  45. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ ϫʔΧʔεϨουͰಈ࡞ ᶄ࠶։ͯ͠୅ೖ 6*εϨουͰಈ࡞ ᶅ7JFXʹ൓ө ྫ֎࣌͸ͬͪ͜
  46. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } } ᶃݺͼग़ͯ͠தஅ͢Δ ϫʔΧʔεϨουͰಈ࡞ ᶄ࠶։ͯ͠୅ೖ 6*εϨουͰಈ࡞ ᶅ7JFXʹ൓ө ྫ֎࣌͸ͬͪ͜ Ωϟϯηϧ είʔϓ͕ऴྃͨ͠ ͸ͬͪ͜
  47. ©2018 Lang-8 Inc. ALL Rights Reserved. ඇಉظॲཧΛॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) view.showProfile(profile) } catch(e:CancellationException) { // no op } catch (e: Exception) { view.showError(e) } } }
  48. ©2018 Lang-8 Inc. ALL Rights Reserved. ௚ྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) { requestTicketCount(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) val ticketCount = getTicketCount(id) view.showProfile(profile, ticketCount) } catch (e: Exception) { view.showError(e) } } }
  49. ©2018 Lang-8 Inc. ALL Rights Reserved. ௚ྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) { requestProfile(id) } suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) { requestTicketCount(id) } fun showProfile(id: Int) { launch { try { val profile = getProfile(id) val ticketCount = getTicketCount(id) view.showProfile(profile, ticketCount) } catch (e: Exception) { view.showError(e) } } }
  50. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } }
  51. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } }
  52. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } } DPSPVUJOF4DPQFؔ਺Λ࢖ͬͯ ࢠείʔϓΛ։࢝͢Δ
  53. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } } BTZODؔ਺ͰίϧʔνϯΛෳ਺ىಈ͢Δ
  54. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒྻʹॻ͘ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } } ଴ͪ߹ΘͤΔ
  55. ©2018 Lang-8 Inc. ALL Rights Reserved. DPSPVUJOF4DPQFؔ਺͕ͳ͔ͬͨΒ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { val profile = async { getProfile(id) } val tickets = async { getTicket(profile.id) } view.showProfile(profile.await(), tickets.await()) } catch (e: Exception) { view.showError(e) } } }
  56. ©2018 Lang-8 Inc. ALL Rights Reserved. DPSPVUJOF4DPQFؔ਺͕ͳ͔ͬͨΒ suspend fun getProfile(id:

    Int): Profile = withContext(Dispatchers.IO) {…} suspend fun getTicketCount(id: Int): Int = withContext(Dispatchers.IO) {…} fun showProfile(id: Int) { launch { try { val profile = async { getProfile(id) } val tickets = async { getTicket(profile.id) } view.showProfile(profile.await(), tickets.await()) } catch (e: Exception) { view.showError(e) } } }
  57. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒߦੑʹ͓͚ΔHPUP void save(int data,

    File file) { try (FileOutputStream out = new FileOutputStream(file);) { new Thread() { @Override public void run() { try { out.write(data); } catch (IOException e) { // error } } }.start(); } catch (IOException e) { // error } }
  58. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒߦੑʹ͓͚ΔHPUP void save(int data,

    File file) { try (FileOutputStream out = new FileOutputStream(file);) { new Thread() { @Override public void run() { try { out.write(data); } catch (IOException e) { // error } } }.start(); } catch (IOException e) { // error } } USZXJUISFTPVSDFTͰϑΝΠϧΛ։͘
  59. ©2018 Lang-8 Inc. ALL Rights Reserved. void save(int data, File

    file) { try (FileOutputStream out = new FileOutputStream(file);) { new Thread() { @Override public void run() { try { out.write(data); } catch (IOException e) { // error } } }.start(); } catch (IOException e) { // error } } ฒߦੑʹ͓͚ΔHPUP USZXJUISFTPVSDFTͷதͰεϨου Λىಈͯ͠PVUʹ৮ͬͯ΋ඞͣDMPTFࡁ ΈͳͷͰΤϥʔʹͳΔ
  60. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒߦੑΛߏ଄Խ͢Δ fun showProfile(id: Int)

    { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } }
  61. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒߦੑΛߏ଄Խ͢Δ fun showProfile(id: Int)

    { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } } 1BSFOU4DPQF $IJME4DPQF MBVODI BTZOD BTZOD
  62. ©2018 Lang-8 Inc. ALL Rights Reserved. είʔϓͱྫ֎ 1BSFOU4DPQF $IJME4DPQF MBVODI

    BTZOD BTZOD είʔϓ಺ͷฒߦ෼ذͷ͍ͣΕ͔͕ΤϥʔʹͳΔͱ είʔϓશମ͕Τϥʔ Ωϟϯηϧ ʹͳΔ
  63. ©2018 Lang-8 Inc. ALL Rights Reserved. DPSPVUJOF4DPQFؔ਺ fun showProfile(id: Int)

    { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(profile.id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } } UISPX&YDFQUJPO
  64. ©2018 Lang-8 Inc. ALL Rights Reserved. DPSPVUJOF4DPQFؔ਺ fun showProfile(id: Int)

    { launch { try { coroutineScope { val profile = async { getProfile(id) } val tickets = async { getTicket(profile.id) } view.showProfile(profile.await(), tickets.await()) } } catch (e: Exception) { view.showError(e) } } } ࢠείʔϓ͕ऴྃ͠ྫ֎͕ඈΜͰ͘Δ
  65. ©2018 Lang-8 Inc. ALL Rights Reserved. DPSPVUJOF4DPQFؔ਺͕ͳ͔ͬͨΒ fun showProfile(id: Int)

    { launch { try { val profile = async { requestProfile(id) } val tickets = async { requestTicket(profile.id) } view.showProfile(profile.await(), tickets.await()) } catch (e: Exception) { view.showError(e) } } }
  66. ©2018 Lang-8 Inc. ALL Rights Reserved. ฒྻॲཧΛॻ͘ wίϧʔνϯͷதͰίϧʔνϯ ෼ذ Λىಈ͢Δ৔

    ߹͸DPSPVUJOF4DPQFؔ਺Λ࢖͏ είʔϓͷ ֊૚ߏ଄Λߟ͑Δ  wMBVODIBTZODΛωετͯ͠Δ࣌͸஫ҙ w෼ذ͕Τϥʔʹͳͬͯ΋είʔϓΛܧଓͰ͖Δ TVQFSWJTPS4DPQFؔ਺͕͋Δ ࠓճ͸লུ IUUQTLPUMJOHJUIVCJPLPUMJOYDPSPVUJOFTLPUMJOYDPSPVUJOFTDPSFLPUMJOYDPSPVUJOFTTVQFSWJTPSTDPQFIUNM
  67. ©2018 Lang-8 Inc. ALL Rights Reserved. 3Y+BWBͱͷ౷߹ wLPUMJOYDPSPVUJOFTSYΛ࢖͏ w4JOHMF .BZCF

    $PNQMFUBCMFͳͲΛ TVTQFOEؔ਺ʹͰ͖Δ wTVTQFOEؔ਺Λ4JOHMF .BZCF  $PNQMFUBCMFͳͲͰ͖Δ IUUQTHJUIVCDPN,PUMJOLPUMJOYDPSPVUJOFTUSFFNBTUFSSFBDUJWFLPUMJOYDPSPVUJOFTSY
  68. ©2018 Lang-8 Inc. ALL Rights Reserved. 4JOHMFΛTVTQFOEؔ਺ʹ͢Δ interface RemoteService {

    @GET("/profile") fun getProfile(id: Int): Single<Profile> }
  69. ©2018 Lang-8 Inc. ALL Rights Reserved. 4JOHMFΛTVTQFOEؔ਺ʹ͢Δ interface RemoteService {

    @GET("/profile") fun getProfile(id: Int): Single<Profile> } val profile = withContext { service.getProfile(id).await() } 4JOHMFͷ֦ுؔ਺ʹ BXBJU ͕௥Ճ͞Ε͍ͯΔ
  70. ©2018 Lang-8 Inc. ALL Rights Reserved. TVTQFOEؔ਺Λ4JOHMFʹ͢Δ fun getProfile(id: Int):

    Single<Profile> { return rxSingle { Profile(id) } } TVTQFOEϥϜμΛड͚औͬͯ݁ՌΛ 4JOHMFͰฦؔ͢਺
  71. ©2018 Lang-8 Inc. ALL Rights Reserved. TVTQFOEؔ਺Λ4JOHMFʹ͢Δ fun getProfile(id: Int):

    Single<Profile> { return rxSingle { Profile(id) } } TVTQFOEϥϜμΛड͚औͬͯ݁ՌΛ 4JOHMFͰฦؔ͢਺ Τϥʔʹͳͬͯ΋਌είʔϓΛ Ωϟϯηϧ͠ͳ͍
  72. ©2018 Lang-8 Inc. ALL Rights Reserved. 3Y+BWBXJUI$PSPVUJPOF w LPUMJOYDPSPVUJOFTSYͰ૬ޓͷΠϯςάϨʔγϣ ϯ͕Մೳ

    w ྫ͑͹ෳࡶʹ߹੒͕ඞཁͳՕॴͳͲ͸ίϧʔνϯͰϑϥο τʹॻ͍ͯ࠷ޙʹ4JOHMFʹ͢Δͱ͔͕͍͍͔΋ w ରཱ͢Δ΋ͷͰ͸ͳ͍ͷͰ͍͍ײ͡ʹ࢖͏ͷ͕ྑ͍ ͓͢ ͢Ί͸4JOHMF .BZCF $PNQMFUBCMFͷஔ͖׵͑
  73. ©2018 Lang-8 Inc. ALL Rights Reserved. 8PSL.BOBHFSͱ$PSPVUJOF8PSLFS class MyWorker(context: Context,

    param: WorkerParameters) : CoroutineWorker(context, param) { override val coroutineContext = Dispatchers.IO override suspend fun doWork(): Payload { return Payload(Result.SUCCESS) } }
  74. ©2018 Lang-8 Inc. ALL Rights Reserved. 8PSL.BOBHFSͱ$PSPVUJOF8PSLFS class MyWorker(context: Context,

    param: WorkerParameters) : CoroutineWorker(context, param) { override val coroutineContext = Dispatchers.IO override suspend fun doWork(): Payload { return Payload(Result.SUCCESS) } } EP8PSLؔ਺͕TVTQFOEؔ਺ʹͳΔ
  75. ©2018 Lang-8 Inc. ALL Rights Reserved. 8PSL.BOBHFSͱ$PSPVUJOF8PSLFS class MyWorker(context: Context,

    param: WorkerParameters) : CoroutineWorker(context, param) { override val coroutineContext = Dispatchers.IO override suspend fun doWork(): Payload { return Payload(Result.SUCCESS) } } ΦʔόʔϥΠυͰ͖Δɻ σϑΥϧτ͸%JTQBUDIFST%FGBVMU
  76. ©2018 Lang-8 Inc. ALL Rights Reserved. 8PSL.BOBHFSͱ$PSPVUJOF8PSLFS class MyWorker(context: Context,

    param: WorkerParameters) : CoroutineWorker(context, param) { override val coroutineContext = Dispatchers.IO override suspend fun doWork(): Payload { return Payload(Result.SUCCESS) } } ໭Γ஋͕8PSLFSͱ͸ҟͳΔɻ PVUQVU%BUBΛ໌ࣔతʹ౉͢ඞཁ͕͋Δ
  77. ©2018 Lang-8 Inc. ALL Rights Reserved. 8PSL.BOBHFSͱ$PSPVUJOF8PSLFS class MyWorker(context: Context,

    param: WorkerParameters) : CoroutineWorker(context, param) { override val coroutineContext = Dispatchers.IO override suspend fun doWork(): Payload { return Payload(Result.SUCCESS) } } ໭Γ஋͕8PSLFSͱ͸ҟͳΔɻ PVUQVU%BUBΛ໌ࣔతʹ౉͢ඞཁ͕͋Δ public Payload(@NonNull Result result, @NonNull Data output) { mResult = result; mOutput = output; }
  78. ©2018 Lang-8 Inc. ALL Rights Reserved. 3PPNͱTVTQFOEؔ਺ @Dao interface UserDao

    { @Insert suspend fun insert(user: User) @Update suspend fun update(user: User) @Query("SELECT * FROM user") suspend fun getAllUsers(): List<User> @Delete suspend fun delete(user: User) }
  79. ©2018 Lang-8 Inc. ALL Rights Reserved. 3PPNͱTVTQFOEؔ਺ val job =

    Job() val scope = CoroutineScope(Dispatchers.Main + job) scope.launch { try { val dao = db.userDao() dao.insert(User(firstName = "Jack", lastName = "Jill")) // do something } catch (e: java.lang.Exception) { // insert error } }
  80. ©2018 Lang-8 Inc. ALL Rights Reserved. 3PPNͱTVTQFOEؔ਺ val job =

    Job() val scope = CoroutineScope(Dispatchers.Main + job) scope.launch { try { val dao = db.userDao() dao.insert(User(firstName = "Jack", lastName = "Jill")) // do something } catch (e: java.lang.Exception) { // insert error } } ಺෦ͰXJUI$POUFYUؔ਺͕ݺͼग़͞ΕΔ
  81. ©2018 Lang-8 Inc. ALL Rights Reserved. 3PPNͱTVTQFOEؔ਺ val job =

    Job() val scope = CoroutineScope(Dispatchers.Main + job) scope.launch { try { val dao = db.userDao() dao.insert(User(firstName = "Jack", lastName = "Jill")) // do something } catch (e: java.lang.Exception) { // insert error } } ಺෦ͰXJUI$POUFYUؔ਺͕ݺͼग़͞ΕΔ 3PPNͷ2VFSZ&YFDVUPSΛ %JTQBUDIFSʹ͍ͯ͠Δ
  82. ©2018 Lang-8 Inc. ALL Rights Reserved. TVTQFOEؔ਺ͱ2VFSZ&YFDVUPS val db =

    Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).apply { val dispatcher = Dispatchers.IO if (dispatcher is ExecutorCoroutineDispatcher) { setQueryExecutor(dispatcher.executor) } }.build()
  83. ©2018 Lang-8 Inc. ALL Rights Reserved. TVTQFOEؔ਺ͱ2VFSZ&YFDVUPS val db =

    Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).apply { val dispatcher = Dispatchers.IO if (dispatcher is ExecutorCoroutineDispatcher) { setQueryExecutor(dispatcher.executor) } }.build() 3PPN#VJMEFSͰ&YFDVUPSΛઃఆͰ͖Δ
  84. ©2018 Lang-8 Inc. ALL Rights Reserved. ·ͱΊ w ίϧʔνϯ͸লϝϞϦɺॻ͖΍͍͢ ಡΈ΍͍͢

    ɺϥΠϒϥϦͱ ͯ͠΋ܰྔ w $PSPVUJOF4DPQFͱϥΠϑαΠΫϧΛ࣋ͭίϯϙʔωϯτΛ૊ Έ߹Θͤͯ࢖͏ w ୯७ͳඇಉظॲཧ͸XJUI$POUFYUؔ਺Ͱେ఍͸ΧόʔͰ͖Δ w ฒྻͰίϧʔνϯΛىಈ͢Δ৔߹͸είʔϓͷ֊૚Λҙࣝ͢Δඞ ཁ͕͋Δɻ w 3Yͱ͸ରཱ͠ͳ͍ɻҰ෦ͷॲཧ͕ஔ͖׵͕͑Ͱ͖Δ͔΋ w +FUQBDLͰ΋ଓʑαϙʔτ͕ਐΜͰಋೖ͠΍͘͢ͳ͖͍ͬͯͯΔ
  85. ©2018 Lang-8 Inc. ALL Rights Reserved. ©2018 Lang-8 Inc. ALL

    Rights Reserved. ͋Γ͕ͱ͏͍͟͝·ͨ͠