SlideShare a Scribd company logo
Session 5 l RGP Korea 권태환
코루틴 적용 및 ReactiveX(RxJava)와 비교
Session 5. Android Kotlin coroutin
Tae-hwan
소개
GDG Seoul 운영진
드로이드 나이츠 운영진
RGP Korea(요기요/배달통) - 요기요 안드로이드 개발
Blog : 꿈 많은 개발자가 되자! https://thdev.tech
Kotlin coroutines
Kotlin 얼마나 활용 중이신가요?
저희는
Kotlin extensions + Higher-Order function
Coroutines 적용
버튼 클릭 처리
요기요 Java : 59.9% / Kotlin : 39.9%
Google 발표 자료
In fact, 27% of the top 1,000 Android apps on Google Play already use
Kotlin.
More importantly, Android developers are loving the language with over
97% satisfaction in our most recent survey. It's no surprise that Kotlin
was voted as the #2 most-loved language in the 2018 StackOverflow
survey.
출처 : https://android-developers.googleblog.com/2018/10/kotlin-momentum-for-android-and-beyond.html
Kotlin coroutines
Subroutine
Subroutine
In computer programming, a subroutine is a sequence of program
instructions that performs a specific task, packaged as a unit
In different programming languages, a subroutine may be called a
procedure, a function, a routine, a method, or a subprogram. The generic
term callable unit is sometimes used.
출처 : https://en.wikipedia.org/wiki/Subroutine
Subroutine
fun test() fun MutableList<Int>.sum()
mutableList().sum()
return sum()
subroutine의 return이 불러지기 전까진

test()의 다음 라인을 실행하지 않는다.
Subroutine example
private fun MutableList<Int>.sum(): Int =
this.sumBy { it }
@Test
fun test() {
val sum = (0..10).toMutableList().sum()
println(sum)
}
sum이 끝나야 return
sum이 끝나야 println
Coroutines
According to Donald Knuth, Melvin Conway coined the term coroutine in
1958 when he applied it to construction of an assembly program.
The first published explanation of the coroutine appeared later, in 1963
출처 : https://en.wikipedia.org/wiki/Coroutine
Coroutines
Coroutines are computer-program components that
generalize subroutines for non-preemptive multitasking, by allowing
multiple entry points for suspending and resuming execution at certain
locations. Coroutines are well-suited for implementing familiar program
components such as cooperative tasks, exceptions, event
loops, iterators, infinite lists and pipes.
출처 : https://en.wikipedia.org/wiki/Coroutine
정리하면
Coroutines
Entry point 여러 개 허용하는 subroutine
언제든 일시 정지하고 다시 실행 가능
event loops, iterators, 무한 리스트, 파이프 같은 것을 구현하는데 적합
Coroutines
Entry point 여러 개 허용하는 subroutine
Coroutines
Entry point 여러 개 허용하는 subroutine
no. 1 Out 0 .. no. 2 Out 0 .. no. 4 Out 5 .. no. 5 Out 5
End no. 1 Done! .. no. 9 Out 4 .. End no. 2 Done! .. no. 6 Out 5
End no. 3 Done! .. End no. 4 Done! .. no. 8 Out 5 .. End no. 5 Done!
no. 9 Out 5 .. End no. 6 Done! .. no. 10 Out 5 .. End no. 7 Done!
no. 11 Out 5 .. End no. 8 Done! .. no. 12 Out 5 .. End no. 9 Done!
Coroutines
Start routine fun Int.countDown()
Loop
fun Int.countDown()
Loop
fun Int.countDown()
Loop
fun Int.countDown()
Loop
10.countDown()
.
.
.
Entry point 여러 개 허용하는 subroutine
Coroutines example
private suspend fun Int.countDown(currentIndex: Int) {
for (index in this downTo 1) { // countdown from 10 to 1
tv_message.text = "Now index $currentIndex Countdown $index" // update text
delay(200)
}
Log.i("TEMP", "Now index $currentIndex Done!")
}
Thread[main,5,main]
Android UI
Entry point 여러 개 허용하는 subroutine
var currentIndex = 0
fab.onClick {
CoroutineScope(Dispatchers.Main).launch {
10.countDown(++currentIndex)
}
}
Kotlin coroutines
Kotlin coroutines
Kotlin 1.3과 함께 coroutines 1.0 정식이 나왔습니다.
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0'
Kotlin coroutines
Kotlin 다양한 platform 제공
Server-side
Desktop
Mobile Application
다양한 언어에서 제공하던 주요 라이브러리 제공
C#, ECMAScript : async/await
Go : channels, select
C#, Python : generators/yield
더 자세한 내용은 https://kotlinlang.org/docs/reference/coroutines-overview.html
Coroutine
light-weight threads
Kotlin coroutines guide
Coroutines
https://kotlinlang.org/docs/reference/coroutines/coroutines-
guide.html
Android Coroutines - codelab
https://codelabs.developers.google.com/codelabs/kotlin-coroutines/
index.html
Kotlin coroutines
blocking과 non-blocking
CoroutineScope, GlobalScope
suspend
Job
여기서 알아볼 내용
blocking과 non-blocking
Kotlin coroutines
@Test
fun test() {
GlobalScope.launch { // launch new coroutine in background and continue
delay(300L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(500L) // block main thread for 2 seconds to keep JVM alive
}
blocking과 non-blocking
Main Thread에서 Thread.sleep(500L)을 부르면
0.5초동안 앱이 멈추는 현상 발생 후 넘어간다.
Kotlin coroutines
Thread.sleep() : Thread 처리 전까지 Main Thread가 멈춘다.
delay : 별도의 coroutine에서 동작하여 멈추지 않고 넘어간다.
blocking과 non-blocking
Kotlin coroutines
@Test
fun test()
CoroutineScope(Dispatchers.Unconfined).launch {
delay(300L)
println("World!")
}
println("Hello,")
}
runBlocking
Result
Subroutine
Coroutine
delay(500)
runBlocking {
}
={
Kotlin coroutines
runBlocking은 함수의 처리가 끝날때까지 대기
delay()를 걸어두면 delay 시간만큼 대기하고 return
Android에서 runBlocking을 UI에서 잘못 사용하면 멈추는 현상 발생
runBlocking
delay를 이용해 non-blocking을 할 수 있음
runBlocking, CoroutineScope, GlobalScope 안에서 동작해야 함
delay
Kotlin coroutines
CoroutineScope
GlobalScope
Coroutines을 시작하기 위한 Scope
CoroutineScope
Kotlin coroutines
가장 기본적인 Scope
Thread 형태를 지정(Main, Default, IO 등을 지정)
CoroutineScope(Main, Default, IO …).
launch, async 등을 통해 scope을 실행
CoroutineScope
Kotlin coroutines
Activity/Fragment Lifecycle에 따라야 한다
onDestroy() : cancel 하도록 코드 추가
CoroutineScope(/* thread type */).launch {}로 실행
launch {}의 return job의 동작을 지정 가능
join() : scope 동작이 끝날때까지 대기하며, suspend에서 호출 가능
cancel() : 동작을 종료하도록 호출
start() : scope이 아직 시작하지 않을 경우 start, scope의 상태를 확인
CoroutineScope 중요한 점
Kotlin coroutines
@Suppress("FunctionName")
public fun CoroutineScope(context: CoroutineContext): CoroutineScope =
ContextScope(if (context[Job] != null) context else context + Job())
CoroutineScope의 interface 정의
public interface CoroutineScope {
@Deprecated(level = DeprecationLevel.HIDDEN, message = "Deprecated in favor of
top-level extension property")
public val isActive: Boolean
get() = coroutineContext[Job]?.isActive ?: true
/**
* Context of this scope. */
public val coroutineContext: CoroutineContext
}
Kotlin coroutines
@Test
fun test() = runBlocking {
CoroutineScope(Dispatchers.Unconfined).launch {
delay(300L)
println("World!")
}
println("Hello,")
delay(500L)
}
CoroutineScope 활용
Delay 대신 coroutine의 return인 job.join()을 사용
Kotlin coroutines
@Test
fun test() = runBlocking {
delay(300L)
println("World!")
}
println("Hello,")
}
CoroutineScope 활용 - Delay 대신 job.join()
delay(500L)
CoroutineScope(Dispatchers.Unconfined).launch {
job.join()
val job =
Kotlin coroutines
@Test
fun test() = runBlocking {
val job = CoroutineScope(Dispatchers.Unconfined).launch {
delay(300L)
println("World!")
}
println("Hello,")
job.join()
}
CoroutineScope 활용
새로운 scope을 생성하고
default로 launch
launch에서 CoroutineScope에서
지정한 default Thread로 사용
join()으로 default thread 종료하기 전까지 대기
GlobalScope
Kotlin coroutines
CoroutineScope 상속 받아 구현
Demon, Application 등에서 사용
Application의 lifetime에 따라 동작하는 scope에서 사용 추천
GlobalScope는 Dispatchers.Unconfined(worker thread)에서 동작
GlobalScope.launch(/* thread type */) {}로 실행
GlobalScope
Kotlin coroutines
object GlobalScope : CoroutineScope {
/**
* @suppress **Deprecated**: Deprecated in favor of top-level extension property
*/
@Deprecated(level = DeprecationLevel.HIDDEN,
message = "Deprecated in favor of top-level extension property")
override val isActive: Boolean
get() = true
/**
* Returns [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
GlobalScope API 코드
Kotlin coroutines
fun ReceiveChannel<Int>.sqrt(): ReceiveChannel<Double> =
for (number in this@sqrt) {
send(Math.sqrt(number.toDouble()))
}
GlobalScope 사용 예
GlobalScope.produce(Dispatchers.Unconfined) {
}
suspend
Kotlin coroutines
suspend를 활용하여 함수 분할 할 수 있다
Suspend 키워드를 사용하는 함수는 CoroutineScope에서 만 사용할 수 있다.
suspend
Kotlin coroutines
suspend fun CoroutineScope.loadData(
body: suspend CoroutineScope.(item: String) -> Unit) {
val item = ""
body(item)
}
loadData { item ->
// Coroutine scope 정의
}
suspend
suspend
CoroutineScope(Dispatchers.Main).launch {
}
delay(100L)
Job
Kotlin coroutines
CoroutineScope의 return에는 job 객체를 넘겨준다.
이 job을 통해 routine의 취소, 실행, 종료를 대기할 수 있다
job.cancel() : 종료하도록 유도한다
job.join() : 종료를 대기하며 호출은 suspend에서 가능하다
job.start() : coroutine의 시작을 확인할 수 있으며, 시작 상태라면 true
Job
Count down 구현
Kotlin coroutines
var currentIndex = 0
fab.onClick {
CoroutineScope(Dispatchers.Default).launch {
val job = launch(Dispatchers.Main) {
10.countDown(++currentIndex)
}
job.join()
}
}
private suspend fun Int.countDown(currentIndex: Int) {
for (index in this downTo 1) { // countdown from 10 to 1
tv_message.text = "Now index $currentIndex Countdown $index" // update text
delay(200)
}
Log.i("TEMP", "Now index $currentIndex Done!")
}
Count down
새로운 scope을 생성하고
default로 launch
launch를 Main Thread로 변경
join()으로 UI thread 종료하기 전까지 대기
상위 scope thread에 따름
여기서는 UI
Android onClick
RxJava vs coroutines
Android onClick - RxJava vs coroutines
private val clickEventSubject = PublishSubject.create<View>()
private var currentIndex = 0
fab.setOnClickListener {
clickEventSubject.onNext(it)
}
clickEventSubject
.throttleFirst(500, TimeUnit.MICROSECONDS)
.observeOn(Schedulers.io())
.map {
currentIndex++
}
.switchMap {
Observable.zip(Observable.range(0, 10),
Observable.interval(200, TimeUnit.MILLISECONDS),
BiFunction<Int, Long, Int> { range, _ ->
10 - range
})
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ index ->
tv_message.text = "Now index $currentIndex Countdown $index"
}, {})
RxJava Countdown 구현
onClick 처리를 위한
Subject 생성
첫 번째만 처리하기 위한 throttleFirst
0..10까지 출력을 위한 ragne
200ms 처리를 위한 interval
UI thread로 변경하고, 메시지 노출
Android onClick - Learning curve
출처 : 구글 이미지 검색
Android onClick - RxJava vs coroutines
Observable과 Streams
기존 Thread 보다 간단한 코드로 처리
stream을 통해 데이터 처리 용이
Thread간 교체가 간단
RxJava를 활용한 수 많은 라이브러리 활용
가능
러닝커브가 높음
용어를 모르면 코드 활용 이유를 알 수 없음
RxJava Kotlin coroutines
함수 형태라 읽기 쉽다
light-weight threads
모든 routine 동작을 개발자가 처리 가능
아직은 필요한 라이브러리를 구현해서 사용
해야 함
RxView와 같은 라이브러리 개발 필요
Android onClick - RxJava vs coroutines
private val clickEventSubject =
PublishSubject.create<View>()
private var currentIndex = 0
fab.setOnClickListener {
clickEventSubject.onNext(it)
}
clickEventSubject
.throttleFirst(500, TimeUnit.MICROSECONDS)
.observeOn(Schedulers.io())
.map {
currentIndex++
}
.switchMap {
Observable.zip(Observable.range(0, 10),
Observable.interval(200, TimeUnit.MILLISECONDS),
BiFunction<Int, Long, Int> { range, _ ->
10 - range
})
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ index ->
tv_message.text = "Now index $currentIndex Countdown
$index"
}, {})
RxJava Countdown 구현
var currentIndex = 0
fab.onClick {
}
private suspend fun Int.countDown(currentIndex: Int) {
Log.i("TEMP", "Now index $currentIndex Done!")
}
CoroutineScope(Dispatchers.Default).launch {
val job = launch(Dispatchers.Main) {
10.countDown(++currentIndex)
}
job.join()
}
for (index in this downTo 1) {
}
tv_message.text = "Now index $currentIndex
Countdown $index"
delay(200)
Coroutines Countdown 구현
어느게 읽기(이해하기) 더 쉽나요?
한번 읽어보죠
Android onClick - RxJava vs coroutines
private val clickEventSubject =
PublishSubject.create<View>()
private var currentIndex = 0
fab.setOnClickListener {
clickEventSubject.onNext(it)
}
clickEventSubject
.throttleFirst(500, TimeUnit.MICROSECONDS)
.observeOn(Schedulers.io())
.map {
currentIndex++
}
.switchMap {
Observable.zip(Observable.range(0, 10),
Observable.interval(200, TimeUnit.MILLISECONDS),
BiFunction<Int, Long, Int> { range, _ ->
10 - range
})
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ index ->
tv_message.text = "Now index $currentIndex Countdown
$index"
}, {})
RxJava Countdown 구현
var currentIndex = 0
fab.onClick {
}
private suspend fun Int.countDown(currentIndex: Int) {
Log.i("TEMP", "Now index $currentIndex Done!")
}
CoroutineScope(Dispatchers.Default).launch {
val job = launch(Dispatchers.Main) {
10.countDown(++currentIndex)
}
job.join()
}
for (index in this downTo 1) {
}
tv_message.text = "Now index $currentIndex
Countdown $index"
delay(200)
Coroutines Countdown 구현
Android onClick - RxJava vs coroutines
처음 학습 비용이 높다
수 많은 라이브러리 활용 가능
예제도 많고, 문서도 잘 되어있다.
RxJava Kotlin coroutines
처음 학습 비용이 낮다
아직은 부족한 라이브러리
직접 만들 수 있고, 문서도 잘 되어있다
Android onClick
잘 활용하기
Android onClick 잘 활용하기
첫 번째 이벤트 만 허용하기 위해서
throttleFirst 활용
시간으로 first의 시간을 지정하여 아래와 같은 문제 발생
해결 : 데이터 처리가 끝나면 버튼의 상태를 변경
중간에 오류날 가능성을 대비한 예외처리 필요
RxJava 버튼 처리
Android onClick 잘 활용하기
첫 번째 이벤트 만 허용하기 위해서
버튼의 상태를 변경해서 처리한다?
다행히도 coroutine에서는 그럴 필요 없다.
Coroutine으로 처리
GlobalScope 활용
Android onClick 잘 활용하기
private fun View.onClick(action: suspend (View) -> Unit) {
val event = GlobalScope.actor<View>(Dispatchers.Main) {
for (event in channel) action(event)
}
setOnClickListener {
event.offer(it)
}
}
var currentIndex = 0
fab.onClick {
10.countDown(currentIndex++)
}
Coroutine GlobalScope.actor<T> 활용하기
1. Singletone의 GlobalScope 활용
2. actor 이용 event 받기
3. actor에 offer로 event 보내기
4. 받은 event를 Higher-Order function으로 넘겨서 정의하도록 한다.
6. 람다 표현으로 countDown 구현
5. 이때 Higher-Order function 정의는 suspend가 포함되어야 한다
Android onClick 잘 활용하기
Coroutine GlobalScope.actor<T> 활용하기
Android coroutines
UnitTest/Main Thread에서 활용하기 쉽게 Dispatchers 하나로 활용
UnitTest에서 Main thread를 활용할 수 없기에 기본으로 처리 할 수 있도록 작성
CoroutineScope을 Base에 작성하여 release를 쉽게 하도록 처리
onClick에 coroutine 활용을 위한 GlobalScope 적용
안드로이드에서 코루틴 활용
Android Coroutines
Android Coroutines
sealed class DispatchersProviderSealed {
open val main: CoroutineContext by lazy { Dispatchers.Main }
open val default: CoroutineContext by lazy { Dispatchers.Default }
}
/**
* 기타 Thread를 위한 Dispatchers 정의
*/
object DispatchersProvider : DispatchersProviderSealed()
/**
* Unit Test를 위한 Dispatchers 정의
*/
object TestDispatchersProvider : DispatchersProviderSealed() {
override val main: CoroutineContext = Dispatchers.Unconfined
override val default: CoroutineContext = Dispatchers.Unconfined
}
Dispatchers 정의(UnitTest/Default Thread)
Android Coroutines
abstract class CoroutineScopeActivity : AppCompatActivity(), CoroutineScope {
private val job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
}
CoroutineScope을 상속받아 구현
onDestroy()에서 job을 종료하도록 한다.
Job을 미리 생성하여
CoroutineContext에 미리 지정 할 수 있다.
Activity에서 사용할 기본 Context를 정의한다.
CoroutineScope을 상속받아 구현하면 기본 CoroutineScope으로 정의되어있다
launch, actor<E>을 사용하면 코드 간결 및 자동으로 종료 처리 해준다.
Default 상위 Activity에서 정의한 CoroutineScope의 Thread를 활용한다
필요시 launch, actor에서 Thread를 언제든 변경 가능하다
다양한 CoroutineScope 구현
ViewModel
LifecycleObservable
Fragment
CoroutineScope을 상속받아 구현
Android Coroutines
Android Coroutines
abstract class CoroutineScopeActivity : CoroutineScopeActivity() {
launch {
// UI Thread에서 처리
}
launch(Dispatchers.Default) {
// Default Thread에서 처리
}
actor<Generic Type> {
// UI Thread에서 event 처리
for (event in channel) action(event)
}
actor<Generic Type>(Dispatchers.Default) {
// Default Thead에서 처리
for (event in channel) action(event)
}
}
CoroutineScope 상속 받은 Activity에서 routine 사용하기
launch, actor에서는 언제든지
Thread type을 변경할 수 있다.
Higher-Order function + kotlin Extensions을 활용
GlobalScope을 활용하거나, CoroutineScope을 활용 할 수 있다
동작 범위에 따라서 GlobalScope, CoroutineScope을 선택함이 좋다
onClick 처리
Android Coroutines
Android Coroutines
class CoroutinesSendChannelOnClickEvent<E>(
private val view: View,
private val bgBody: suspend (item: View) -> E,
private val dispatcherProvider: DispatchersProviderSealed = DispatchersProvider,
private val job: Job? = null) {
fun consumeEach(uiBody: (item: E) -> Unit): CoroutinesSendChannelOnClickEvent<E> {
val clickActor = CoroutineScope(dispatcherProvider.main + (job
?: EmptyCoroutineContext)).actor<View> {
this.channel.map(context = dispatcherProvider.default, transform = bgBody).consumeEach(uiBody)
}
view.setOnClickListener { clickActor.offer(it) }
return this
}
}
fun <E> View.onClick(dispatcherProvider: DispatchersProviderSealed = DispatchersProvider,
job: Job? = null, bgBody: suspend (item: View) -> E): CoroutinesSendChannelOnClickEvent<E> =
CoroutinesSendChannelOnClickEvent(this, bgBody, dispatcherProvider, job)
infix fun <E> CoroutinesSendChannelOnClickEvent<E>.consume(uiBody: (item: E) -> Unit) {
this.consumeEach(uiBody)
}
onClick 만들기, background에서 처리하고, UI에 던져주기
View : click을 위한 View
background : Higher-Order Function
Provider : 지정
Job : 종료 처리를 위한 job 추가
Offer 처리를 위한 CoroutineScope 생성
생성을 간단하게 하기 위한 function 2개
Android Coroutines
fab.onClick(job = job) {
loadNetwork()
} consume {
tv_message.text = it
}
private suspend fun loadNetwork(): String {
delay(300)
return "currentIndex ${currentIndex++}"
}
onClick 만들기, background에서 처리하고, UI에 던져주기
click을 처리하고,
background에서 loadNetwork()
Temp load network
이미 JakeWharton 배포.
Dependency 추가
implementation ‘com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
Deferred<E>를 활용하여 return을 처리할 수 있다.
Retrofit2 kotlin coroutines adapter
Android Coroutines
interface RetrofitService {
@GET("/posts")
fun getPosts(): Deferred<Response<List<Post>>>
}
Android Coroutines
object RetrofitFactory {
const val BASE_URL = “https://url"
fun makeRetrofitService(): RetrofitService {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(CoroutineCallAdapterFactory()
)
.build().create(RetrofitService::class.java)
}
}
Retrofit2 kotlin coroutines adapter
Android Coroutines
launch {
val request = service.getPosts()
val response = request.await()
if (response.isSuccessful) {
// Pass in the response.body() to your adapter
} else {
toast("Error ${response.code()}")
}
}
Retrofit2 kotlin coroutines adapter
감사합니다.
Tae-hwan
taehwan@thdev.net

More Related Content

What's hot

Kotlin presentation
Kotlin presentation Kotlin presentation
Kotlin presentation
MobileAcademy
 
Introduction to Kotlin Language and its application to Android platform
Introduction to Kotlin Language and its application to Android platformIntroduction to Kotlin Language and its application to Android platform
Introduction to Kotlin Language and its application to Android platform
EastBanc Tachnologies
 
Android | Android Activity Launch Modes and Tasks | Gonçalo Silva
Android | Android Activity Launch Modes and Tasks | Gonçalo SilvaAndroid | Android Activity Launch Modes and Tasks | Gonçalo Silva
Android | Android Activity Launch Modes and Tasks | Gonçalo Silva
JAX London
 
Ios development
Ios developmentIos development
Ios development
Shakil Ahmed
 
React hooks
React hooksReact hooks
React hooks
Sadhna Rana
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
ASG
 
Kotlin Multiplatform
Kotlin MultiplatformKotlin Multiplatform
Kotlin Multiplatform
Kevin Galligan
 
Kotlin on android
Kotlin on androidKotlin on android
Kotlin on android
Kurt Renzo Acosta
 
Jetpack Compose beginner.pdf
Jetpack Compose beginner.pdfJetpack Compose beginner.pdf
Jetpack Compose beginner.pdf
AayushmaAgrawal
 
Chapter 1 introduction to java technology
Chapter 1 introduction to java technologyChapter 1 introduction to java technology
Chapter 1 introduction to java technologysshhzap
 
State management in react applications (Statecharts)
State management in react applications (Statecharts)State management in react applications (Statecharts)
State management in react applications (Statecharts)
Tomáš Drenčák
 
Flutter state management from zero to hero
Flutter state management from zero to heroFlutter state management from zero to hero
Flutter state management from zero to hero
Ahmed Abu Eldahab
 
Intro to kotlin
Intro to kotlinIntro to kotlin
Intro to kotlin
Tomislav Homan
 
Dropwizard
DropwizardDropwizard
Dropwizard
Scott Leberknight
 
Try Jetpack Compose
Try Jetpack ComposeTry Jetpack Compose
Try Jetpack Compose
LutasLin
 
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
Muhammad Abdullah
 
Kotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxKotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptx
takshilkunadia
 
Introduction to thymeleaf
Introduction to thymeleafIntroduction to thymeleaf
Introduction to thymeleaf
NexThoughts Technologies
 
Introduction to Koltin for Android Part I
Introduction to Koltin for Android Part I Introduction to Koltin for Android Part I
Introduction to Koltin for Android Part I
Atif AbbAsi
 
Android & iOS Automation Using Appium
Android & iOS Automation Using AppiumAndroid & iOS Automation Using Appium
Android & iOS Automation Using Appium
Mindfire Solutions
 

What's hot (20)

Kotlin presentation
Kotlin presentation Kotlin presentation
Kotlin presentation
 
Introduction to Kotlin Language and its application to Android platform
Introduction to Kotlin Language and its application to Android platformIntroduction to Kotlin Language and its application to Android platform
Introduction to Kotlin Language and its application to Android platform
 
Android | Android Activity Launch Modes and Tasks | Gonçalo Silva
Android | Android Activity Launch Modes and Tasks | Gonçalo SilvaAndroid | Android Activity Launch Modes and Tasks | Gonçalo Silva
Android | Android Activity Launch Modes and Tasks | Gonçalo Silva
 
Ios development
Ios developmentIos development
Ios development
 
React hooks
React hooksReact hooks
React hooks
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Kotlin Multiplatform
Kotlin MultiplatformKotlin Multiplatform
Kotlin Multiplatform
 
Kotlin on android
Kotlin on androidKotlin on android
Kotlin on android
 
Jetpack Compose beginner.pdf
Jetpack Compose beginner.pdfJetpack Compose beginner.pdf
Jetpack Compose beginner.pdf
 
Chapter 1 introduction to java technology
Chapter 1 introduction to java technologyChapter 1 introduction to java technology
Chapter 1 introduction to java technology
 
State management in react applications (Statecharts)
State management in react applications (Statecharts)State management in react applications (Statecharts)
State management in react applications (Statecharts)
 
Flutter state management from zero to hero
Flutter state management from zero to heroFlutter state management from zero to hero
Flutter state management from zero to hero
 
Intro to kotlin
Intro to kotlinIntro to kotlin
Intro to kotlin
 
Dropwizard
DropwizardDropwizard
Dropwizard
 
Try Jetpack Compose
Try Jetpack ComposeTry Jetpack Compose
Try Jetpack Compose
 
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
 
Kotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxKotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptx
 
Introduction to thymeleaf
Introduction to thymeleafIntroduction to thymeleaf
Introduction to thymeleaf
 
Introduction to Koltin for Android Part I
Introduction to Koltin for Android Part I Introduction to Koltin for Android Part I
Introduction to Koltin for Android Part I
 
Android & iOS Automation Using Appium
Android & iOS Automation Using AppiumAndroid & iOS Automation Using Appium
Android & iOS Automation Using Appium
 

Similar to [25]안드로이드에서 코루틴은 어떻게 적용할 수 있을까?: 코루틴 적용 및 ReactiveX(RxJava/RxKotlin)와 비교한다면?

[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
NAVER D2
 
[Google I_O Extended Daejeon 2023] 처음 시작하는 Flutter
[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter
[Google I_O Extended Daejeon 2023] 처음 시작하는 Flutter
SuJang Yang
 
코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우
Arawn Park
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
상현 조
 
Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래
Leonardo YongUk Kim
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
NAVER D2
 
GDB와 strace로 Hang 걸린 Python Process 원격 디버깅
GDB와 strace로 Hang 걸린 Python Process 원격 디버깅GDB와 strace로 Hang 걸린 Python Process 원격 디버깅
GDB와 strace로 Hang 걸린 Python Process 원격 디버깅
Youngmin Koo
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
흥배 최
 
C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013
명신 김
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
Dong Chan Shin
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
Nam Hyeonuk
 
Python으로 채팅 구현하기
Python으로 채팅 구현하기Python으로 채팅 구현하기
Python으로 채팅 구현하기
Tae Young Lee
 
유니티3D coroutine 활용
유니티3D coroutine 활용유니티3D coroutine 활용
유니티3D coroutine 활용
Sangwook Kwon
 
Visual studio 2010
Visual studio 2010Visual studio 2010
Visual studio 2010
MinGeun Park
 
비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018
비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018
비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018
Harry Oh
 
Open Source Engineering V2
Open Source Engineering V2Open Source Engineering V2
Open Source Engineering V2YoungSu Son
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표
Kwen Won Lee
 
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
Daehee Kim
 
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
Chris Ohk
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509
영석 조
 

Similar to [25]안드로이드에서 코루틴은 어떻게 적용할 수 있을까?: 코루틴 적용 및 ReactiveX(RxJava/RxKotlin)와 비교한다면? (20)

[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
 
[Google I_O Extended Daejeon 2023] 처음 시작하는 Flutter
[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter
[Google I_O Extended Daejeon 2023] 처음 시작하는 Flutter
 
코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우코틀린 멀티플랫폼, 미지와의 조우
코틀린 멀티플랫폼, 미지와의 조우
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
 
Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래Kotlin 2.0을 통해 알아보는 코틀린의 미래
Kotlin 2.0을 통해 알아보는 코틀린의 미래
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
GDB와 strace로 Hang 걸린 Python Process 원격 디버깅
GDB와 strace로 Hang 걸린 Python Process 원격 디버깅GDB와 strace로 Hang 걸린 Python Process 원격 디버깅
GDB와 strace로 Hang 걸린 Python Process 원격 디버깅
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013C++ 개발자와 함께 하는 visual studio 2013
C++ 개발자와 함께 하는 visual studio 2013
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
Python으로 채팅 구현하기
Python으로 채팅 구현하기Python으로 채팅 구현하기
Python으로 채팅 구현하기
 
유니티3D coroutine 활용
유니티3D coroutine 활용유니티3D coroutine 활용
유니티3D coroutine 활용
 
Visual studio 2010
Visual studio 2010Visual studio 2010
Visual studio 2010
 
비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018
비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018
비트코인 블록체인에 영구불변 메시지 개발 삽질기 - Google Next Extended Seoul 2018
 
Open Source Engineering V2
Open Source Engineering V2Open Source Engineering V2
Open Source Engineering V2
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표
 
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
 
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509
 

More from NAVER Engineering

React vac pattern
React vac patternReact vac pattern
React vac pattern
NAVER Engineering
 
디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX
NAVER Engineering
 
진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)
NAVER Engineering
 
서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트
NAVER Engineering
 
BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호
NAVER Engineering
 
이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라
NAVER Engineering
 
날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기
NAVER Engineering
 
쏘카프레임 구축 배경과 과정
 쏘카프레임 구축 배경과 과정 쏘카프레임 구축 배경과 과정
쏘카프레임 구축 배경과 과정
NAVER Engineering
 
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
NAVER Engineering
 
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
NAVER Engineering
 
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
NAVER Engineering
 
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
NAVER Engineering
 
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
NAVER Engineering
 
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
NAVER Engineering
 
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
NAVER Engineering
 
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
NAVER Engineering
 
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
NAVER Engineering
 
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
NAVER Engineering
 
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
NAVER Engineering
 
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
NAVER Engineering
 

More from NAVER Engineering (20)

React vac pattern
React vac patternReact vac pattern
React vac pattern
 
디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX
 
진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)
 
서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트
 
BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호
 
이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라
 
날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기
 
쏘카프레임 구축 배경과 과정
 쏘카프레임 구축 배경과 과정 쏘카프레임 구축 배경과 과정
쏘카프레임 구축 배경과 과정
 
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
 
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
 
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
 
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
 
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
 
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
 
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
 
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
 
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
 
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
 
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
 
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
 

[25]안드로이드에서 코루틴은 어떻게 적용할 수 있을까?: 코루틴 적용 및 ReactiveX(RxJava/RxKotlin)와 비교한다면?

  • 1.
  • 2.
  • 3. Session 5 l RGP Korea 권태환
  • 4. 코루틴 적용 및 ReactiveX(RxJava)와 비교 Session 5. Android Kotlin coroutin Tae-hwan
  • 5. 소개 GDG Seoul 운영진 드로이드 나이츠 운영진 RGP Korea(요기요/배달통) - 요기요 안드로이드 개발 Blog : 꿈 많은 개발자가 되자! https://thdev.tech
  • 7. Kotlin 얼마나 활용 중이신가요?
  • 8. 저희는 Kotlin extensions + Higher-Order function Coroutines 적용 버튼 클릭 처리 요기요 Java : 59.9% / Kotlin : 39.9%
  • 9. Google 발표 자료 In fact, 27% of the top 1,000 Android apps on Google Play already use Kotlin. More importantly, Android developers are loving the language with over 97% satisfaction in our most recent survey. It's no surprise that Kotlin was voted as the #2 most-loved language in the 2018 StackOverflow survey. 출처 : https://android-developers.googleblog.com/2018/10/kotlin-momentum-for-android-and-beyond.html
  • 12. Subroutine In computer programming, a subroutine is a sequence of program instructions that performs a specific task, packaged as a unit In different programming languages, a subroutine may be called a procedure, a function, a routine, a method, or a subprogram. The generic term callable unit is sometimes used. 출처 : https://en.wikipedia.org/wiki/Subroutine
  • 13. Subroutine fun test() fun MutableList<Int>.sum() mutableList().sum() return sum() subroutine의 return이 불러지기 전까진
 test()의 다음 라인을 실행하지 않는다.
  • 14. Subroutine example private fun MutableList<Int>.sum(): Int = this.sumBy { it } @Test fun test() { val sum = (0..10).toMutableList().sum() println(sum) } sum이 끝나야 return sum이 끝나야 println
  • 15. Coroutines According to Donald Knuth, Melvin Conway coined the term coroutine in 1958 when he applied it to construction of an assembly program. The first published explanation of the coroutine appeared later, in 1963 출처 : https://en.wikipedia.org/wiki/Coroutine
  • 16. Coroutines Coroutines are computer-program components that generalize subroutines for non-preemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes. 출처 : https://en.wikipedia.org/wiki/Coroutine
  • 18. Coroutines Entry point 여러 개 허용하는 subroutine 언제든 일시 정지하고 다시 실행 가능 event loops, iterators, 무한 리스트, 파이프 같은 것을 구현하는데 적합
  • 19. Coroutines Entry point 여러 개 허용하는 subroutine
  • 20. Coroutines Entry point 여러 개 허용하는 subroutine no. 1 Out 0 .. no. 2 Out 0 .. no. 4 Out 5 .. no. 5 Out 5 End no. 1 Done! .. no. 9 Out 4 .. End no. 2 Done! .. no. 6 Out 5 End no. 3 Done! .. End no. 4 Done! .. no. 8 Out 5 .. End no. 5 Done! no. 9 Out 5 .. End no. 6 Done! .. no. 10 Out 5 .. End no. 7 Done! no. 11 Out 5 .. End no. 8 Done! .. no. 12 Out 5 .. End no. 9 Done!
  • 21. Coroutines Start routine fun Int.countDown() Loop fun Int.countDown() Loop fun Int.countDown() Loop fun Int.countDown() Loop 10.countDown() . . . Entry point 여러 개 허용하는 subroutine
  • 22. Coroutines example private suspend fun Int.countDown(currentIndex: Int) { for (index in this downTo 1) { // countdown from 10 to 1 tv_message.text = "Now index $currentIndex Countdown $index" // update text delay(200) } Log.i("TEMP", "Now index $currentIndex Done!") } Thread[main,5,main] Android UI Entry point 여러 개 허용하는 subroutine var currentIndex = 0 fab.onClick { CoroutineScope(Dispatchers.Main).launch { 10.countDown(++currentIndex) } }
  • 24. Kotlin coroutines Kotlin 1.3과 함께 coroutines 1.0 정식이 나왔습니다. implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0'
  • 25. Kotlin coroutines Kotlin 다양한 platform 제공 Server-side Desktop Mobile Application 다양한 언어에서 제공하던 주요 라이브러리 제공 C#, ECMAScript : async/await Go : channels, select C#, Python : generators/yield 더 자세한 내용은 https://kotlinlang.org/docs/reference/coroutines-overview.html Coroutine light-weight threads
  • 26. Kotlin coroutines guide Coroutines https://kotlinlang.org/docs/reference/coroutines/coroutines- guide.html Android Coroutines - codelab https://codelabs.developers.google.com/codelabs/kotlin-coroutines/ index.html
  • 27. Kotlin coroutines blocking과 non-blocking CoroutineScope, GlobalScope suspend Job 여기서 알아볼 내용
  • 29. Kotlin coroutines @Test fun test() { GlobalScope.launch { // launch new coroutine in background and continue delay(300L) // non-blocking delay for 1 second (default time unit is ms) println("World!") // print after delay } println("Hello,") // main thread continues while coroutine is delayed Thread.sleep(500L) // block main thread for 2 seconds to keep JVM alive } blocking과 non-blocking Main Thread에서 Thread.sleep(500L)을 부르면 0.5초동안 앱이 멈추는 현상 발생 후 넘어간다.
  • 30. Kotlin coroutines Thread.sleep() : Thread 처리 전까지 Main Thread가 멈춘다. delay : 별도의 coroutine에서 동작하여 멈추지 않고 넘어간다. blocking과 non-blocking
  • 31. Kotlin coroutines @Test fun test() CoroutineScope(Dispatchers.Unconfined).launch { delay(300L) println("World!") } println("Hello,") } runBlocking Result Subroutine Coroutine delay(500) runBlocking { } ={
  • 32. Kotlin coroutines runBlocking은 함수의 처리가 끝날때까지 대기 delay()를 걸어두면 delay 시간만큼 대기하고 return Android에서 runBlocking을 UI에서 잘못 사용하면 멈추는 현상 발생 runBlocking delay를 이용해 non-blocking을 할 수 있음 runBlocking, CoroutineScope, GlobalScope 안에서 동작해야 함 delay
  • 35. Kotlin coroutines 가장 기본적인 Scope Thread 형태를 지정(Main, Default, IO 등을 지정) CoroutineScope(Main, Default, IO …). launch, async 등을 통해 scope을 실행 CoroutineScope
  • 36. Kotlin coroutines Activity/Fragment Lifecycle에 따라야 한다 onDestroy() : cancel 하도록 코드 추가 CoroutineScope(/* thread type */).launch {}로 실행 launch {}의 return job의 동작을 지정 가능 join() : scope 동작이 끝날때까지 대기하며, suspend에서 호출 가능 cancel() : 동작을 종료하도록 호출 start() : scope이 아직 시작하지 않을 경우 start, scope의 상태를 확인 CoroutineScope 중요한 점
  • 37. Kotlin coroutines @Suppress("FunctionName") public fun CoroutineScope(context: CoroutineContext): CoroutineScope = ContextScope(if (context[Job] != null) context else context + Job()) CoroutineScope의 interface 정의 public interface CoroutineScope { @Deprecated(level = DeprecationLevel.HIDDEN, message = "Deprecated in favor of top-level extension property") public val isActive: Boolean get() = coroutineContext[Job]?.isActive ?: true /** * Context of this scope. */ public val coroutineContext: CoroutineContext }
  • 38. Kotlin coroutines @Test fun test() = runBlocking { CoroutineScope(Dispatchers.Unconfined).launch { delay(300L) println("World!") } println("Hello,") delay(500L) } CoroutineScope 활용 Delay 대신 coroutine의 return인 job.join()을 사용
  • 39. Kotlin coroutines @Test fun test() = runBlocking { delay(300L) println("World!") } println("Hello,") } CoroutineScope 활용 - Delay 대신 job.join() delay(500L) CoroutineScope(Dispatchers.Unconfined).launch { job.join() val job =
  • 40. Kotlin coroutines @Test fun test() = runBlocking { val job = CoroutineScope(Dispatchers.Unconfined).launch { delay(300L) println("World!") } println("Hello,") job.join() } CoroutineScope 활용 새로운 scope을 생성하고 default로 launch launch에서 CoroutineScope에서 지정한 default Thread로 사용 join()으로 default thread 종료하기 전까지 대기
  • 42. Kotlin coroutines CoroutineScope 상속 받아 구현 Demon, Application 등에서 사용 Application의 lifetime에 따라 동작하는 scope에서 사용 추천 GlobalScope는 Dispatchers.Unconfined(worker thread)에서 동작 GlobalScope.launch(/* thread type */) {}로 실행 GlobalScope
  • 43. Kotlin coroutines object GlobalScope : CoroutineScope { /** * @suppress **Deprecated**: Deprecated in favor of top-level extension property */ @Deprecated(level = DeprecationLevel.HIDDEN, message = "Deprecated in favor of top-level extension property") override val isActive: Boolean get() = true /** * Returns [EmptyCoroutineContext]. */ override val coroutineContext: CoroutineContext get() = EmptyCoroutineContext } GlobalScope API 코드
  • 44. Kotlin coroutines fun ReceiveChannel<Int>.sqrt(): ReceiveChannel<Double> = for (number in this@sqrt) { send(Math.sqrt(number.toDouble())) } GlobalScope 사용 예 GlobalScope.produce(Dispatchers.Unconfined) { }
  • 46. Kotlin coroutines suspend를 활용하여 함수 분할 할 수 있다 Suspend 키워드를 사용하는 함수는 CoroutineScope에서 만 사용할 수 있다. suspend
  • 47. Kotlin coroutines suspend fun CoroutineScope.loadData( body: suspend CoroutineScope.(item: String) -> Unit) { val item = "" body(item) } loadData { item -> // Coroutine scope 정의 } suspend suspend CoroutineScope(Dispatchers.Main).launch { } delay(100L)
  • 48. Job
  • 49. Kotlin coroutines CoroutineScope의 return에는 job 객체를 넘겨준다. 이 job을 통해 routine의 취소, 실행, 종료를 대기할 수 있다 job.cancel() : 종료하도록 유도한다 job.join() : 종료를 대기하며 호출은 suspend에서 가능하다 job.start() : coroutine의 시작을 확인할 수 있으며, 시작 상태라면 true Job
  • 51. Kotlin coroutines var currentIndex = 0 fab.onClick { CoroutineScope(Dispatchers.Default).launch { val job = launch(Dispatchers.Main) { 10.countDown(++currentIndex) } job.join() } } private suspend fun Int.countDown(currentIndex: Int) { for (index in this downTo 1) { // countdown from 10 to 1 tv_message.text = "Now index $currentIndex Countdown $index" // update text delay(200) } Log.i("TEMP", "Now index $currentIndex Done!") } Count down 새로운 scope을 생성하고 default로 launch launch를 Main Thread로 변경 join()으로 UI thread 종료하기 전까지 대기 상위 scope thread에 따름 여기서는 UI
  • 53. Android onClick - RxJava vs coroutines private val clickEventSubject = PublishSubject.create<View>() private var currentIndex = 0 fab.setOnClickListener { clickEventSubject.onNext(it) } clickEventSubject .throttleFirst(500, TimeUnit.MICROSECONDS) .observeOn(Schedulers.io()) .map { currentIndex++ } .switchMap { Observable.zip(Observable.range(0, 10), Observable.interval(200, TimeUnit.MILLISECONDS), BiFunction<Int, Long, Int> { range, _ -> 10 - range }) } .observeOn(AndroidSchedulers.mainThread()) .subscribe({ index -> tv_message.text = "Now index $currentIndex Countdown $index" }, {}) RxJava Countdown 구현 onClick 처리를 위한 Subject 생성 첫 번째만 처리하기 위한 throttleFirst 0..10까지 출력을 위한 ragne 200ms 처리를 위한 interval UI thread로 변경하고, 메시지 노출
  • 54. Android onClick - Learning curve 출처 : 구글 이미지 검색
  • 55. Android onClick - RxJava vs coroutines Observable과 Streams 기존 Thread 보다 간단한 코드로 처리 stream을 통해 데이터 처리 용이 Thread간 교체가 간단 RxJava를 활용한 수 많은 라이브러리 활용 가능 러닝커브가 높음 용어를 모르면 코드 활용 이유를 알 수 없음 RxJava Kotlin coroutines 함수 형태라 읽기 쉽다 light-weight threads 모든 routine 동작을 개발자가 처리 가능 아직은 필요한 라이브러리를 구현해서 사용 해야 함 RxView와 같은 라이브러리 개발 필요
  • 56. Android onClick - RxJava vs coroutines private val clickEventSubject = PublishSubject.create<View>() private var currentIndex = 0 fab.setOnClickListener { clickEventSubject.onNext(it) } clickEventSubject .throttleFirst(500, TimeUnit.MICROSECONDS) .observeOn(Schedulers.io()) .map { currentIndex++ } .switchMap { Observable.zip(Observable.range(0, 10), Observable.interval(200, TimeUnit.MILLISECONDS), BiFunction<Int, Long, Int> { range, _ -> 10 - range }) } .observeOn(AndroidSchedulers.mainThread()) .subscribe({ index -> tv_message.text = "Now index $currentIndex Countdown $index" }, {}) RxJava Countdown 구현 var currentIndex = 0 fab.onClick { } private suspend fun Int.countDown(currentIndex: Int) { Log.i("TEMP", "Now index $currentIndex Done!") } CoroutineScope(Dispatchers.Default).launch { val job = launch(Dispatchers.Main) { 10.countDown(++currentIndex) } job.join() } for (index in this downTo 1) { } tv_message.text = "Now index $currentIndex Countdown $index" delay(200) Coroutines Countdown 구현 어느게 읽기(이해하기) 더 쉽나요? 한번 읽어보죠
  • 57. Android onClick - RxJava vs coroutines private val clickEventSubject = PublishSubject.create<View>() private var currentIndex = 0 fab.setOnClickListener { clickEventSubject.onNext(it) } clickEventSubject .throttleFirst(500, TimeUnit.MICROSECONDS) .observeOn(Schedulers.io()) .map { currentIndex++ } .switchMap { Observable.zip(Observable.range(0, 10), Observable.interval(200, TimeUnit.MILLISECONDS), BiFunction<Int, Long, Int> { range, _ -> 10 - range }) } .observeOn(AndroidSchedulers.mainThread()) .subscribe({ index -> tv_message.text = "Now index $currentIndex Countdown $index" }, {}) RxJava Countdown 구현 var currentIndex = 0 fab.onClick { } private suspend fun Int.countDown(currentIndex: Int) { Log.i("TEMP", "Now index $currentIndex Done!") } CoroutineScope(Dispatchers.Default).launch { val job = launch(Dispatchers.Main) { 10.countDown(++currentIndex) } job.join() } for (index in this downTo 1) { } tv_message.text = "Now index $currentIndex Countdown $index" delay(200) Coroutines Countdown 구현
  • 58. Android onClick - RxJava vs coroutines 처음 학습 비용이 높다 수 많은 라이브러리 활용 가능 예제도 많고, 문서도 잘 되어있다. RxJava Kotlin coroutines 처음 학습 비용이 낮다 아직은 부족한 라이브러리 직접 만들 수 있고, 문서도 잘 되어있다
  • 60. Android onClick 잘 활용하기 첫 번째 이벤트 만 허용하기 위해서 throttleFirst 활용 시간으로 first의 시간을 지정하여 아래와 같은 문제 발생 해결 : 데이터 처리가 끝나면 버튼의 상태를 변경 중간에 오류날 가능성을 대비한 예외처리 필요 RxJava 버튼 처리
  • 61. Android onClick 잘 활용하기 첫 번째 이벤트 만 허용하기 위해서 버튼의 상태를 변경해서 처리한다? 다행히도 coroutine에서는 그럴 필요 없다. Coroutine으로 처리
  • 63. Android onClick 잘 활용하기 private fun View.onClick(action: suspend (View) -> Unit) { val event = GlobalScope.actor<View>(Dispatchers.Main) { for (event in channel) action(event) } setOnClickListener { event.offer(it) } } var currentIndex = 0 fab.onClick { 10.countDown(currentIndex++) } Coroutine GlobalScope.actor<T> 활용하기 1. Singletone의 GlobalScope 활용 2. actor 이용 event 받기 3. actor에 offer로 event 보내기 4. 받은 event를 Higher-Order function으로 넘겨서 정의하도록 한다. 6. 람다 표현으로 countDown 구현 5. 이때 Higher-Order function 정의는 suspend가 포함되어야 한다
  • 64. Android onClick 잘 활용하기 Coroutine GlobalScope.actor<T> 활용하기
  • 66. UnitTest/Main Thread에서 활용하기 쉽게 Dispatchers 하나로 활용 UnitTest에서 Main thread를 활용할 수 없기에 기본으로 처리 할 수 있도록 작성 CoroutineScope을 Base에 작성하여 release를 쉽게 하도록 처리 onClick에 coroutine 활용을 위한 GlobalScope 적용 안드로이드에서 코루틴 활용 Android Coroutines
  • 67. Android Coroutines sealed class DispatchersProviderSealed { open val main: CoroutineContext by lazy { Dispatchers.Main } open val default: CoroutineContext by lazy { Dispatchers.Default } } /** * 기타 Thread를 위한 Dispatchers 정의 */ object DispatchersProvider : DispatchersProviderSealed() /** * Unit Test를 위한 Dispatchers 정의 */ object TestDispatchersProvider : DispatchersProviderSealed() { override val main: CoroutineContext = Dispatchers.Unconfined override val default: CoroutineContext = Dispatchers.Unconfined } Dispatchers 정의(UnitTest/Default Thread)
  • 68. Android Coroutines abstract class CoroutineScopeActivity : AppCompatActivity(), CoroutineScope { private val job: Job = Job() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onDestroy() { super.onDestroy() job.cancel() } } CoroutineScope을 상속받아 구현 onDestroy()에서 job을 종료하도록 한다. Job을 미리 생성하여 CoroutineContext에 미리 지정 할 수 있다. Activity에서 사용할 기본 Context를 정의한다.
  • 69. CoroutineScope을 상속받아 구현하면 기본 CoroutineScope으로 정의되어있다 launch, actor<E>을 사용하면 코드 간결 및 자동으로 종료 처리 해준다. Default 상위 Activity에서 정의한 CoroutineScope의 Thread를 활용한다 필요시 launch, actor에서 Thread를 언제든 변경 가능하다 다양한 CoroutineScope 구현 ViewModel LifecycleObservable Fragment CoroutineScope을 상속받아 구현 Android Coroutines
  • 70. Android Coroutines abstract class CoroutineScopeActivity : CoroutineScopeActivity() { launch { // UI Thread에서 처리 } launch(Dispatchers.Default) { // Default Thread에서 처리 } actor<Generic Type> { // UI Thread에서 event 처리 for (event in channel) action(event) } actor<Generic Type>(Dispatchers.Default) { // Default Thead에서 처리 for (event in channel) action(event) } } CoroutineScope 상속 받은 Activity에서 routine 사용하기 launch, actor에서는 언제든지 Thread type을 변경할 수 있다.
  • 71. Higher-Order function + kotlin Extensions을 활용 GlobalScope을 활용하거나, CoroutineScope을 활용 할 수 있다 동작 범위에 따라서 GlobalScope, CoroutineScope을 선택함이 좋다 onClick 처리 Android Coroutines
  • 72. Android Coroutines class CoroutinesSendChannelOnClickEvent<E>( private val view: View, private val bgBody: suspend (item: View) -> E, private val dispatcherProvider: DispatchersProviderSealed = DispatchersProvider, private val job: Job? = null) { fun consumeEach(uiBody: (item: E) -> Unit): CoroutinesSendChannelOnClickEvent<E> { val clickActor = CoroutineScope(dispatcherProvider.main + (job ?: EmptyCoroutineContext)).actor<View> { this.channel.map(context = dispatcherProvider.default, transform = bgBody).consumeEach(uiBody) } view.setOnClickListener { clickActor.offer(it) } return this } } fun <E> View.onClick(dispatcherProvider: DispatchersProviderSealed = DispatchersProvider, job: Job? = null, bgBody: suspend (item: View) -> E): CoroutinesSendChannelOnClickEvent<E> = CoroutinesSendChannelOnClickEvent(this, bgBody, dispatcherProvider, job) infix fun <E> CoroutinesSendChannelOnClickEvent<E>.consume(uiBody: (item: E) -> Unit) { this.consumeEach(uiBody) } onClick 만들기, background에서 처리하고, UI에 던져주기 View : click을 위한 View background : Higher-Order Function Provider : 지정 Job : 종료 처리를 위한 job 추가 Offer 처리를 위한 CoroutineScope 생성 생성을 간단하게 하기 위한 function 2개
  • 73. Android Coroutines fab.onClick(job = job) { loadNetwork() } consume { tv_message.text = it } private suspend fun loadNetwork(): String { delay(300) return "currentIndex ${currentIndex++}" } onClick 만들기, background에서 처리하고, UI에 던져주기 click을 처리하고, background에서 loadNetwork() Temp load network
  • 74. 이미 JakeWharton 배포. Dependency 추가 implementation ‘com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' Deferred<E>를 활용하여 return을 처리할 수 있다. Retrofit2 kotlin coroutines adapter Android Coroutines interface RetrofitService { @GET("/posts") fun getPosts(): Deferred<Response<List<Post>>> }
  • 75. Android Coroutines object RetrofitFactory { const val BASE_URL = “https://url" fun makeRetrofitService(): RetrofitService { return Retrofit.Builder() .baseUrl(BASE_URL) .addCallAdapterFactory(CoroutineCallAdapterFactory() ) .build().create(RetrofitService::class.java) } } Retrofit2 kotlin coroutines adapter
  • 76. Android Coroutines launch { val request = service.getPosts() val response = request.await() if (response.isSuccessful) { // Pass in the response.body() to your adapter } else { toast("Error ${response.code()}") } } Retrofit2 kotlin coroutines adapter