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

Kotlin Coroutine 基本的な使い方

sutetotanuki
November 25, 2019

Kotlin Coroutine 基本的な使い方

sutetotanuki

November 25, 2019
Tweet

More Decks by sutetotanuki

Other Decks in Programming

Transcript

  1. $PSPVUJOFͱ͸ fun main(args: Array<String>) { println("Start") GlobalScope.launch { delay(1000) println("1")

    } println("2") println("End") Thread.sleep(2000) } Start 2 End 1 $PSPVUJOFͰ࣮ߦ͞Ε ඇಉظʹॲཧ͞Ε͍ͯΔ
  2. $PSPVUJOFͱ͸ fun main(args: Array<String>) { println("Start") GlobalScope.launch { delay(1000) println("1")

    } println("2") println("End") Thread.sleep(2000) } Start 2 End 1 $PSPVUJOF #VJMEFS $PSPVUJOF 4DPQF
  3. $PSPVUJOF4DPQF fun main(args: Array<String>) = runBlocking { println("Start") GlobalScope.launch {

    delay(1000) println("1") } println("2") println("End") } Start 2 End
  4. $PSPVUJOF4DPQF fun main(args: Array<String>) = runBlocking { println("Start") GlobalScope.launch {

    delay(1000) println("1") } println("2") println("End") } Start 2 End (MPCBM4DPQF ʹͳΔͨΊSVO#MPDLJOHͷ είʔϓͰ͸ऴྃΛ·ͨͳ͍
  5. $PSPVUJOF4DPQF fun main(args: Array<String>) = runBlocking { println("Start") launch {

    delay(1000) println("1") } println("2") println("End") } Start 2 End 1
  6. $PSPVUJOFͱ͸ fun main(args: Array<String>) = runBlocking { println("Start") launch {

    delay(1000) println("1") } println("2") println("End") } Start 2 End 1 SVO#MPDLJOHͷείʔϓͷUIJT͸ $PSPVUJOF4DPQF SVO#MPDLJOHͷ4DPQFͷMBVODIϝιουͰ ࢠ$PSPVUJOF4DPQFΛ࡞੒
  7. $PSPVUJOFͱ͸ fun main(args: Array<String>) = runBlocking { println("Start") launch {

    delay(1000) println("1") } println("2") println("End") } Start 2 End 1
  8. ༻ҙ͞Ε͍ͯΔ%JTQBDIFST 21 εϨου ࠷దͳॲཧ .BJO ϝΠϯ UIΛมߋ͢Δؔ਺ɻLiveDataͷߋ৽ ౳ *0 IOʹ࠷దԽ

    ωοτϫʔΫɺσΟεΫΞΫηεͳͲ %FGBVMU όοΫάϥ΢ϯυ
 εϨουͷڞ༗ϓʔϧ CPUͷෛՙ͕େ͖͍ॲཧɻJSONղੳ ΍Ϧετͷฒͼସ͑౳
  9. $PSPVUJOF%JTQBDIFST fun main(args: Array<String>) = runBlocking { withContext(Dispatchers.IO) { delay(1000)

    println("IO: ${Thread.currentThread().id}") } println("Main: ${Thread.currentThread().id}") } IO: 11 Main: 1
  10. $PSPVUJOF%JTQBDIFST fun main(args: Array<String>) = runBlocking { withContext(Dispatchers.IO) { println("IO:

    ${Thread.currentThread().id}") } println("Main: ${Thread.currentThread().id}") } IO: 11 Main: 1 $PSPVUJOF4DPQFͷUIJTMBVODI ϝιουͰࢠ$PSPVUJOF4DPQFΛ࡞੒ ͢Δ
  11. TVTQFOE suspend fun getData(): ApiResponse { return callApi() } fun

    main(args: Array<String>) { getData() } Suspend function 'getData' should be called only from a coroutine or another suspend function
  12. TVTQFOE suspend fun getData(): ApiResponse { return callApi() } fun

    main(args: Array<String>) { getData() } Suspend function 'getData' should be called only from a coroutine or another suspend function ΤϥʔʹͳΔ
  13. TVTQFOE suspend fun getData(): ApiResponse { return callApi() } fun

    main(args: Array<String>) = runBlocking { getData() } DPSPVUJOFΛىಈͦ͠ͷதͰݺͿͱ Τϥʔ͕ൃੜ͠ͳ͍
  14. 7JFX.PEFMͰ࢖͏ fun callApi(name: String): UserResponseBody { val client = OkHttpClient()

    val request = Request.Builder() .url("https://api.github.com/users/$name") .build() client.newCall(request).execute().use {response -> return Gson().fromJson(response.body?.string(), UserResponseBody::class.java) } } class MainViewModel : ViewModel() { val response = MutableLiveData<UserResponseBody>() val userName = MutableLiveData<String>() fun getUser() { viewModelScope.launch { response.value = callApi(userName.value ?: "") } } }
  15. 7JFX.PEFMͰ࢖͏ class MainViewModel : ViewModel() { val response = MutableLiveData<UserResponseBody>()

    val userName = MutableLiveData<String>() fun getUser() { viewModelScope.launch { response.value = callApi(userName.value ?: "") } } } ϝΠϯεϨουͰΠϯλʔωοτΞΫηε ͢ΔͨΊΤϥʔʹͳΔ WJFX.PEFMͷϥΠϑαΠΫϧͰ؅ཧ͞ΕΔ WJFX.PEFM4DPQFͷ $PSPVUJOF#VJMEFSͰ$PSPVUJOFΛىಈ
  16. ΤϥʔʹͳΒͳ͍Α͏ʹ͢Δ suspend fun callApi(name: String): UserResponseBody = withContext(Dispatchers.IO){ val client

    = OkHttpClient() val request = Request.Builder() .url("https://api.github.com/users/$name") .build() client.newCall(request).execute().use {response -> Gson().fromJson(response.body?.string(), UserResponseBody::class.java) } } TVTQFOEؔ਺ʹ͢Δ %JTQBDIFST*0Ͱىಈ͢ΔΑ͏ʹࢦఆ
  17. class MainViewModel : ViewModel() { val response = MutableLiveData<UserResponseBody>() val

    userName = MutableLiveData<String>("sutetotanuki") val error = MutableLiveData<String>() fun getGithubUser() { viewModelScope.launch { try { response.value = callApi(userName.value ?: "") } catch (e: Throwable) { error.value = e.message } } } } Τϥʔॲཧ TVTQFOEؔ਺ͷΤϥʔ΋ USZDBUDIͰर͑Δ
  18. ίʔϧόοΫؔ਺ override suspend fun initSession() = suspendCoroutine<Unit> { con ->

    CustomerSession.initCustomerSession( context, object : EphemeralKeyProvider { override fun createEphemeralKey( apiVersion: String, keyUpdateListener: EphemeralKeyUpdateListener ) { val ephemeralKeyBody = runBlocking { api.issueEphemeralKey(EphemeralKeyRequest(apiVersion)) } keyUpdateListener.onKeyUpdate(ephemeralKeyBody.string()) con.resume(Unit) } } ) }
  19. 4USJQFͷ &QIFNFSBM,FZ1SPWJEFS import androidx.annotation.Size interface EphemeralKeyProvider { fun createEphemeralKey( @Size(min

    = 4) apiVersion: String, keyUpdateListener: EphemeralKeyUpdateListener ) } BQJ7FSTJPOΛ&QIFNFSBM,FZΛੜ੒͢ ΔαʔόʔαΠυͷ"1*ʹΘͨ͢ LFZ6QEBUF-JTUFOFSʹ"1*͕ੜ੒ͨ͠ &QIFNFSBM,FZΛ౉͢
  20. ίʔϧόοΫؔ਺ suspend fun initSession() = suspendCoroutine<Unit> { con -> CustomerSession.initCustomerSession(

    context, object : EphemeralKeyProvider { override fun createEphemeralKey( apiVersion: String, keyUpdateListener: EphemeralKeyUpdateListener ) { val ephemeralKeyBody = runBlocking { api.issueEphemeralKey(EphemeralKeyRequest(apiVersion)) } keyUpdateListener.onKeyUpdate(ephemeralKeyBody.string()) con.resume(Unit) } } ) } BQJ͕TVTQFOEؔ਺Ͱ࣮૷͞Ε͍ͯΔͷͰ SVO#MPDLJOHͰݺͼͩ͠ "1*ͷϨεϙϯεΛ-JTUFOFSʹઃఆ
  21. ίʔϧόοΫؔ਺ suspend fun initSession() = suspendCoroutine<Unit> { con -> CustomerSession.initCustomerSession(

    context, object : EphemeralKeyProvider { override fun createEphemeralKey( apiVersion: String, keyUpdateListener: EphemeralKeyUpdateListener ) { val ephemeralKeyBody = runBlocking { api.issueEphemeralKey(EphemeralKeyRequest(apiVersion)) } keyUpdateListener.onKeyUpdate(ephemeralKeyBody.string()) con.resume(Unit) } } ) } -JTUFOFSʹ஋Λ౉ͤͨͷͰ SFTVNF ෮ؼ ͢Δ