SlideShare a Scribd company logo
1 of 22
Download to read offline
안드로이드 스레드, Rx 그리고 코루틴
조은실
안드로이드 스레드
프로세스(PROCESS)
메인스레드(MainThreadorUIThread)
App
Events
UI
Drawing
UI
Drawing
UI
Drawing
UI
Drawing
…
작업자스레드(WorkerThread)
리소스를많이소모하는작업
• 앱이실행되면프로세스가생성되고프로세스는VM을실행
• 프로세스가생성될때스레드가하나생성되며,이를메인스레드라고함
• 메인스레드에서는새로운작업을위한스레드를생성하여실행할수있음
안드로이드 스레드
• ANR(ApplicationNotResponding)
• 메인스레드가오랜시간의작업으로차단되면(약5초이상),플랫폼은앱이죽었다고판단하여앱을
종료할수있는ANR다이얼로그를띄움
• 메인스레이드가아닌스레드에서메인스레드의리소스직접접근할경우앱강제종료함
메인스레드
Button.visible=true
작업자스레드
Button.visible=true
버튼보여주세요
메시지전달
O
X
java.lang.IllegalStateException
샘플
https://drive.google.com/open?id=1xJWcYANdXQPc2vmiFhustQRyBF5__HiE
https://github.com/EunsilJo/CoroutineSample
class SleepThread(
private val sleepMillis: Long,
private val handler: Handler
) : Thread() {
companion object {
private const val THREAD_RESULT = "THREAD RESULT!"
}
override fun run() {
super.run()
handler.run {
sendMessage(obtainMessage(SleepMessage.PROGRESS.what, true))
}
try {
sleep(sleepMillis)
handler.run {
sendMessage(obtainMessage(SleepMessage.RESULT.what, THREAD_RESULT))
}
} catch (exception: Exception) {
handler.run {
sendMessage(obtainMessage(SleepMessage.ERROR.what, exception))
}
} finally {
handler.run {
sendMessage(obtainMessage(SleepMessage.PROGRESS.what, false))
}
}
}
}
enum class SleepMessage(val what: Int) {
PROGRESS(0), ERROR(1), RESULT(2)
}
Thread
class SleepHandler(
private val viewModelReference: WeakReference<BaseViewModel>
) : Handler() {
override fun handleMessage(msg: Message?) {
msg?.run {
when (what) {
SleepMessage.PROGRESS.what -> {
viewModelReference.get()?.setLoadingValue(obj as? Boolean ?:
false)
}
SleepMessage.ERROR.what -> {
viewModelReference.get()?.setErrorValue(obj as? Throwable)
}
SleepMessage.RESULT.what -> {
viewModelReference.get()?.setResultValue(obj as? String ?: "")
}
else -> super.handleMessage(msg)
}
} ?: super.handleMessage(msg)
}
}
Thread
class SleepAsyncTask(
private val viewModelReference: WeakReference<BaseViewModel>
) : AsyncTask<Long, Boolean, Pair<String, Throwable?>>() {
companion object {
private const val ASYNC_TASK_RESULT = "ASYNC TASK RESULT!"
}
override fun onPreExecute() {
super.onPreExecute()
viewModelReference.get()?.setLoadingValue(true)
}
override fun doInBackground(vararg millis: Long?): Pair<String, Throwable?> =
try {
Thread.sleep(millis[0] ?: 0L)
ASYNC_TASK_RESULT to null
} catch (exception: Exception) {
"" to exception
}
override fun onPostExecute(result: Pair<String, Throwable?>?) {
super.onPostExecute(result)
viewModelReference.get()?.setLoadingValue(false)
result?.run {
val (value, throwable) = this
when (throwable) {
null -> viewModelReference.get()?.setResultValue(value)
else -> viewModelReference.get()?.setErrorValue(throwable)
}
}
}
}
AsyncTask
class ThreadViewModel : BaseViewModel() {
companion object {
private const val THREAD_POOL_SIZE = 2
}
private val threadPool by lazy { Executors.newFixedThreadPool(THREAD_POOL_SIZE) }
fun getThreadResult(sleepMillis: Long) {
SleepThread(
sleepMillis,
SleepHandler(WeakReference(this@ThreadViewModel))
).also { threadPool.execute(it) }
}
fun getThreadResultWithAsyncTask(sleepMillis: Long) {
SleepAsyncTask(WeakReference(this@ThreadViewModel))
.executeOnExecutor(threadPool, sleepMillis)
}
override fun onCleared() {
super.onCleared()
threadPool.shutdown()
}
}
ThreadViewModel
ReactiveX
• ReactiveX는관찰가능한시퀀스(sequence)를사용하여비동기및이벤트기반프로그램을작성하기위한라
이브러리
• 관찰자패턴(Observerpattern)을확장하여데이터및이벤트의시퀀스를지원
• 로우레벨스레딩(low-levelthreading),동기화,스레드안전성,동시데이터구조및논블로킹(non-bloking)I/O
등을추상화하여지원,오류처리용이함
dependencies	{
implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
implementation	'io.reactivex.rxjava2:rxandroid:2.1.1’
}
Observable
• Observer는Observable을구독
• Observer는Observable이배출하는하나또는연속된항목에반응
• Observer의관찰자를통해Observable의배출알림을받아,동시성연산을가능하게함
onNext, onCompleted, and onError
Subscribe메소드
• Observer와Observable을연결
Observer구현메소드
• onNext
• Observable이새로운항목들을파라미터로배출할때마다호출됨
• onError
• Observable이기대하는데이터가생성되지않았거나다른이유로오류발생시호출됨
• 오류정보를저장하고있는객체를파라미터로전달받음
• onNext,OnCompleted는더이상호출되지않음
• onCompleted
• Observable이마지막onNext를호출한후호출됨(오류가발생하지않았을경우)
ObservableContract
• onNext는0번이상호출가능
• 이후onCompleted또는onError둘중하나를마지막으로호출(모두를호출하지않음)
Single
• Observable의한형태,onSuccess,onError메소드중하나만,한번만호출,메소드가호출되면생명주기끝남,
구독종료됨
• Observable-존재하지않는곳에서부터무한대까지의임의연속값배출
• Observable
• onNext,onError,onCompleted
• Single
• onSuccess-배출하는하나의값전달
• onError-항목을배출할수없을때Throwable전달
그밖에Flowable,Completable,Maybe
class SleepOnSubscribe(private val sleepMillis: Long) : SingleOnSubscribe<String> {
companion object {
private const val RX_RESULT = "RX RESULT!"
}
override fun subscribe(emitter: SingleEmitter<String>) {
if (!emitter.isDisposed) {
try {
Thread.sleep(sleepMillis)
} catch (exception: Exception) {
emitter.onError(exception)
}
emitter.onSuccess(RX_RESULT)
}
}
}
SingleOnSubscribe
class RxViewModel : BaseViewModel() {
private val compositeDisposable by lazy { CompositeDisposable() }
fun getRxResult(sleepMillis: Long) {
Single.create(SleepOnSubscribe(sleepMillis))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { setLoadingValue(true) }
.doFinally { setLoadingValue(false) }
.subscribe(
{ result -> setResultValue(result) },
{ throwable -> setErrorValue(throwable) }
)
.also { compositeDisposable.add(it) }
}
override fun onCleared() {
super.onCleared()
compositeDisposable.dispose()
}
}
RxViewModel
코루틴(Coroutine)
dependencies	{
implementation	'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation	'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1’
}
• 작업실행을일시중지하고다시시작할수있게하여서브루틴을일반화함
• 블로킹코드를작성하는것과동일하게비블로킹코드(비동기프로그래밍)작성가능
• kotlinx.coroutines
• 코틀린언어로코루틴을사용하기위해JetBrains에서개발한라이브러리
• launch,async등제공
Suspending functions
• Suspendingfunctions
• 함수에suspend키워드를추가하여,작업의일시중지,다시시작제어가능
• 다른일시중지함수(suspendingfunctions)나코루틴내에서만호출가능
• CoroutineContext
• Job:백그라운드작업및수명주기를나타내는객체
• ContinuationInterceptor,CoroutineName,CoroutineExceptionHandler
• CoroutineDispatchers
• Dispatchers.Default:기본디스패처,CPU집약적인작업실행에적합
• Dispatchers.IO:CPU를많이사용하지않는IO작업실행에적합
• Dispatchers.Main:UI와상호작용,간단한작업실행에적합
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
val newContext = newCoroutineContext(context)
val coroutine = if (start.isLazy)
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)
coroutine.start(start, coroutine, block)
return coroutine
}
private open class StandaloneCoroutine(
parentContext: CoroutineContext,
active: Boolean
) : AbstractCoroutine<Unit>(parentContext, active) {
override fun handleJobException(exception: Throwable): Boolean {
handleCoroutineException(context, exception)
return true
}
}
Coroutine Builders
• launch
• 백그라운드에서새코루틴시작하고해당Job객체반환
• CoroutineStart.DEFAULT, CoroutineStart.LAZY/ATOMIC/UNDISPATCHED
public fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T> {
val newContext = newCoroutineContext(context)
val coroutine = if (start.isLazy)
LazyDeferredCoroutine(newContext, block) else
DeferredCoroutine<T>(newContext, active = true)
coroutine.start(start, coroutine, block)
return coroutine
}
private open class DeferredCoroutine<T>(
parentContext: CoroutineContext,
active: Boolean
) : AbstractCoroutine<T>(parentContext, active), Deferred<T>, SelectClause1<T> {
override fun getCompleted(): T = getCompletedInternal() as T
override suspend fun await(): T = awaitInternal() as T
override val onAwait: SelectClause1<T> get() = this
override fun <R> registerSelectClause1(select: SelectInstance<R>, block:
suspend (T) -> R) =
registerSelectClause1Internal(select, block)
}
Coroutine Builders
• async
• 백그라운드에서새코루틴시작하고,Job대신지연된Deffered<T>객체반환
class CoroutineViewModel : BaseViewModel() {
companion object {
private const val COROUTINE_RESULT = "COROUTINE RESULT!"
}
private val coroutineScope by lazy { CoroutineScope(Dispatchers.Main) }
fun getCoroutineResult(sleepMillis: Long) =
coroutineScope.launch {
setLoadingValue(true)
try {
setResultValue(sleep(sleepMillis).await())
} catch (exception: Exception) {
setErrorValue(exception)
} finally {
setLoadingValue(false)
}
}
private suspend fun sleep(sleepMillis: Long): Deferred<String> =
CoroutineScope(Dispatchers.IO).async {
Thread.sleep(sleepMillis)
COROUTINE_RESULT
}
override fun onCleared() {
super.onCleared()
coroutineScope.coroutineContext.cancel()
}
}
CoroutineViewModel
안드로이드 스레드, Rx 그리고 코루틴
스레드 Rx 코루틴
+
• 안드로이드기본 • 작업스레드전환쉬움
• 로딩,에러,완료처리쉬움
• 병렬작업용이(zip)
• 네트워크,DB데이터처리를위한
AdapterFactory제공
• 작업처리를위한다양한API제공
• 초기러닝커브낮음
• 작업스레드전환쉬움
• 병렬작업용이(async/wait)
• 필요한작업을순서대로작성하며,
suspend함수선언,변수선언등을통해
비동기작업가능
• 가벼움(?!)
-
• 메인스레드와통신을위해핸들러구현
• 스레드풀구현
• 핸들러클래스에UI갱신을위한객체
전달
• UI갱신시Activity생명주기확인필요
• 병렬작업시결과상태값관리필요
• 네트워크,DB데이터처리를위해콜백
등직접개발필요
• 초기러닝커브높음
• 무거움(?!)
• 네트워크,DB데이터처리를위해콜백
등직접개발필요
참조
• https://developer.android.com/guide/components/processes-and-threads,Processesandthreadsoverview,Android
Developers
• https://developer.android.com/topic/performance/threads,Betterperformancethroughthreading,Android
Developers
• https://developer.android.com/topic/performance/vitals/anr,ANRs,AndroidDevelopers
• https://www.youtube.com/watch?v=qk5F6Bxqhr4&index=1&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE,
ThreadingPerformance101,AndroidDevelopers
• http://reactivex.io/,ReactiveX
• https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html,Corountines,Kotlin
• https://medium.com/androiddevelopers/coroutines-on-android-part-i-getting-the-background-3e0e54d20bb,
CoroutinesonAndroid(partI):Gettingthebackground,SeanMcQuillan
• https://proandroiddev.com/async-operations-with-kotlin-coroutines-part-1-c51cc581ad33,AsyncOperationswith
KotlinCoroutines — Part1,MayowaAdegeye
감사합니다.

More Related Content

Similar to Android Thread, Rx and Coroutine by Eunsil Jo

Deep dive into Android async operations
Deep dive into Android async operationsDeep dive into Android async operations
Deep dive into Android async operationsMateusz Grzechociński
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Introduction to nodejs
Introduction to nodejsIntroduction to nodejs
Introduction to nodejsJames Carr
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications Juliana Lucena
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSTechWell
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)William Farrell
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basicsAnton Narusberg
 
Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JSIlia Idakiev
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with ExpressAaron Stannard
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidEmanuele Di Saverio
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Webnickmbailey
 

Similar to Android Thread, Rx and Coroutine by Eunsil Jo (20)

RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Deep dive into Android async operations
Deep dive into Android async operationsDeep dive into Android async operations
Deep dive into Android async operations
 
Android classes in mumbai
Android classes in mumbaiAndroid classes in mumbai
Android classes in mumbai
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Introduction to nodejs
Introduction to nodejsIntroduction to nodejs
Introduction to nodejs
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JS
 
Android101
Android101Android101
Android101
 
mobl
moblmobl
mobl
 
jsDay 2016 recap
jsDay 2016 recapjsDay 2016 recap
jsDay 2016 recap
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
Mobile optimization
Mobile optimizationMobile optimization
Mobile optimization
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for Android
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Web
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 

Recently uploaded (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 

Android Thread, Rx and Coroutine by Eunsil Jo

  • 1. 안드로이드 스레드, Rx 그리고 코루틴 조은실
  • 3. 안드로이드 스레드 • ANR(ApplicationNotResponding) • 메인스레드가오랜시간의작업으로차단되면(약5초이상),플랫폼은앱이죽었다고판단하여앱을 종료할수있는ANR다이얼로그를띄움 • 메인스레이드가아닌스레드에서메인스레드의리소스직접접근할경우앱강제종료함 메인스레드 Button.visible=true 작업자스레드 Button.visible=true 버튼보여주세요 메시지전달 O X java.lang.IllegalStateException
  • 5. class SleepThread( private val sleepMillis: Long, private val handler: Handler ) : Thread() { companion object { private const val THREAD_RESULT = "THREAD RESULT!" } override fun run() { super.run() handler.run { sendMessage(obtainMessage(SleepMessage.PROGRESS.what, true)) } try { sleep(sleepMillis) handler.run { sendMessage(obtainMessage(SleepMessage.RESULT.what, THREAD_RESULT)) } } catch (exception: Exception) { handler.run { sendMessage(obtainMessage(SleepMessage.ERROR.what, exception)) } } finally { handler.run { sendMessage(obtainMessage(SleepMessage.PROGRESS.what, false)) } } } } enum class SleepMessage(val what: Int) { PROGRESS(0), ERROR(1), RESULT(2) } Thread
  • 6. class SleepHandler( private val viewModelReference: WeakReference<BaseViewModel> ) : Handler() { override fun handleMessage(msg: Message?) { msg?.run { when (what) { SleepMessage.PROGRESS.what -> { viewModelReference.get()?.setLoadingValue(obj as? Boolean ?: false) } SleepMessage.ERROR.what -> { viewModelReference.get()?.setErrorValue(obj as? Throwable) } SleepMessage.RESULT.what -> { viewModelReference.get()?.setResultValue(obj as? String ?: "") } else -> super.handleMessage(msg) } } ?: super.handleMessage(msg) } } Thread
  • 7. class SleepAsyncTask( private val viewModelReference: WeakReference<BaseViewModel> ) : AsyncTask<Long, Boolean, Pair<String, Throwable?>>() { companion object { private const val ASYNC_TASK_RESULT = "ASYNC TASK RESULT!" } override fun onPreExecute() { super.onPreExecute() viewModelReference.get()?.setLoadingValue(true) } override fun doInBackground(vararg millis: Long?): Pair<String, Throwable?> = try { Thread.sleep(millis[0] ?: 0L) ASYNC_TASK_RESULT to null } catch (exception: Exception) { "" to exception } override fun onPostExecute(result: Pair<String, Throwable?>?) { super.onPostExecute(result) viewModelReference.get()?.setLoadingValue(false) result?.run { val (value, throwable) = this when (throwable) { null -> viewModelReference.get()?.setResultValue(value) else -> viewModelReference.get()?.setErrorValue(throwable) } } } } AsyncTask
  • 8. class ThreadViewModel : BaseViewModel() { companion object { private const val THREAD_POOL_SIZE = 2 } private val threadPool by lazy { Executors.newFixedThreadPool(THREAD_POOL_SIZE) } fun getThreadResult(sleepMillis: Long) { SleepThread( sleepMillis, SleepHandler(WeakReference(this@ThreadViewModel)) ).also { threadPool.execute(it) } } fun getThreadResultWithAsyncTask(sleepMillis: Long) { SleepAsyncTask(WeakReference(this@ThreadViewModel)) .executeOnExecutor(threadPool, sleepMillis) } override fun onCleared() { super.onCleared() threadPool.shutdown() } } ThreadViewModel
  • 9. ReactiveX • ReactiveX는관찰가능한시퀀스(sequence)를사용하여비동기및이벤트기반프로그램을작성하기위한라 이브러리 • 관찰자패턴(Observerpattern)을확장하여데이터및이벤트의시퀀스를지원 • 로우레벨스레딩(low-levelthreading),동기화,스레드안전성,동시데이터구조및논블로킹(non-bloking)I/O 등을추상화하여지원,오류처리용이함 dependencies { implementation 'io.reactivex.rxjava2:rxjava:2.2.6' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1’ }
  • 10. Observable • Observer는Observable을구독 • Observer는Observable이배출하는하나또는연속된항목에반응 • Observer의관찰자를통해Observable의배출알림을받아,동시성연산을가능하게함
  • 11. onNext, onCompleted, and onError Subscribe메소드 • Observer와Observable을연결 Observer구현메소드 • onNext • Observable이새로운항목들을파라미터로배출할때마다호출됨 • onError • Observable이기대하는데이터가생성되지않았거나다른이유로오류발생시호출됨 • 오류정보를저장하고있는객체를파라미터로전달받음 • onNext,OnCompleted는더이상호출되지않음 • onCompleted • Observable이마지막onNext를호출한후호출됨(오류가발생하지않았을경우) ObservableContract • onNext는0번이상호출가능 • 이후onCompleted또는onError둘중하나를마지막으로호출(모두를호출하지않음)
  • 12. Single • Observable의한형태,onSuccess,onError메소드중하나만,한번만호출,메소드가호출되면생명주기끝남, 구독종료됨 • Observable-존재하지않는곳에서부터무한대까지의임의연속값배출 • Observable • onNext,onError,onCompleted • Single • onSuccess-배출하는하나의값전달 • onError-항목을배출할수없을때Throwable전달 그밖에Flowable,Completable,Maybe
  • 13. class SleepOnSubscribe(private val sleepMillis: Long) : SingleOnSubscribe<String> { companion object { private const val RX_RESULT = "RX RESULT!" } override fun subscribe(emitter: SingleEmitter<String>) { if (!emitter.isDisposed) { try { Thread.sleep(sleepMillis) } catch (exception: Exception) { emitter.onError(exception) } emitter.onSuccess(RX_RESULT) } } } SingleOnSubscribe
  • 14. class RxViewModel : BaseViewModel() { private val compositeDisposable by lazy { CompositeDisposable() } fun getRxResult(sleepMillis: Long) { Single.create(SleepOnSubscribe(sleepMillis)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { setLoadingValue(true) } .doFinally { setLoadingValue(false) } .subscribe( { result -> setResultValue(result) }, { throwable -> setErrorValue(throwable) } ) .also { compositeDisposable.add(it) } } override fun onCleared() { super.onCleared() compositeDisposable.dispose() } } RxViewModel
  • 16. Suspending functions • Suspendingfunctions • 함수에suspend키워드를추가하여,작업의일시중지,다시시작제어가능 • 다른일시중지함수(suspendingfunctions)나코루틴내에서만호출가능 • CoroutineContext • Job:백그라운드작업및수명주기를나타내는객체 • ContinuationInterceptor,CoroutineName,CoroutineExceptionHandler • CoroutineDispatchers • Dispatchers.Default:기본디스패처,CPU집약적인작업실행에적합 • Dispatchers.IO:CPU를많이사용하지않는IO작업실행에적합 • Dispatchers.Main:UI와상호작용,간단한작업실행에적합
  • 17. public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyStandaloneCoroutine(newContext, block) else StandaloneCoroutine(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine } private open class StandaloneCoroutine( parentContext: CoroutineContext, active: Boolean ) : AbstractCoroutine<Unit>(parentContext, active) { override fun handleJobException(exception: Throwable): Boolean { handleCoroutineException(context, exception) return true } } Coroutine Builders • launch • 백그라운드에서새코루틴시작하고해당Job객체반환 • CoroutineStart.DEFAULT, CoroutineStart.LAZY/ATOMIC/UNDISPATCHED
  • 18. public fun <T> CoroutineScope.async( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T ): Deferred<T> { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyDeferredCoroutine(newContext, block) else DeferredCoroutine<T>(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine } private open class DeferredCoroutine<T>( parentContext: CoroutineContext, active: Boolean ) : AbstractCoroutine<T>(parentContext, active), Deferred<T>, SelectClause1<T> { override fun getCompleted(): T = getCompletedInternal() as T override suspend fun await(): T = awaitInternal() as T override val onAwait: SelectClause1<T> get() = this override fun <R> registerSelectClause1(select: SelectInstance<R>, block: suspend (T) -> R) = registerSelectClause1Internal(select, block) } Coroutine Builders • async • 백그라운드에서새코루틴시작하고,Job대신지연된Deffered<T>객체반환
  • 19. class CoroutineViewModel : BaseViewModel() { companion object { private const val COROUTINE_RESULT = "COROUTINE RESULT!" } private val coroutineScope by lazy { CoroutineScope(Dispatchers.Main) } fun getCoroutineResult(sleepMillis: Long) = coroutineScope.launch { setLoadingValue(true) try { setResultValue(sleep(sleepMillis).await()) } catch (exception: Exception) { setErrorValue(exception) } finally { setLoadingValue(false) } } private suspend fun sleep(sleepMillis: Long): Deferred<String> = CoroutineScope(Dispatchers.IO).async { Thread.sleep(sleepMillis) COROUTINE_RESULT } override fun onCleared() { super.onCleared() coroutineScope.coroutineContext.cancel() } } CoroutineViewModel
  • 20. 안드로이드 스레드, Rx 그리고 코루틴 스레드 Rx 코루틴 + • 안드로이드기본 • 작업스레드전환쉬움 • 로딩,에러,완료처리쉬움 • 병렬작업용이(zip) • 네트워크,DB데이터처리를위한 AdapterFactory제공 • 작업처리를위한다양한API제공 • 초기러닝커브낮음 • 작업스레드전환쉬움 • 병렬작업용이(async/wait) • 필요한작업을순서대로작성하며, suspend함수선언,변수선언등을통해 비동기작업가능 • 가벼움(?!) - • 메인스레드와통신을위해핸들러구현 • 스레드풀구현 • 핸들러클래스에UI갱신을위한객체 전달 • UI갱신시Activity생명주기확인필요 • 병렬작업시결과상태값관리필요 • 네트워크,DB데이터처리를위해콜백 등직접개발필요 • 초기러닝커브높음 • 무거움(?!) • 네트워크,DB데이터처리를위해콜백 등직접개발필요
  • 21. 참조 • https://developer.android.com/guide/components/processes-and-threads,Processesandthreadsoverview,Android Developers • https://developer.android.com/topic/performance/threads,Betterperformancethroughthreading,Android Developers • https://developer.android.com/topic/performance/vitals/anr,ANRs,AndroidDevelopers • https://www.youtube.com/watch?v=qk5F6Bxqhr4&index=1&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE, ThreadingPerformance101,AndroidDevelopers • http://reactivex.io/,ReactiveX • https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html,Corountines,Kotlin • https://medium.com/androiddevelopers/coroutines-on-android-part-i-getting-the-background-3e0e54d20bb, CoroutinesonAndroid(partI):Gettingthebackground,SeanMcQuillan • https://proandroiddev.com/async-operations-with-kotlin-coroutines-part-1-c51cc581ad33,AsyncOperationswith KotlinCoroutines — Part1,MayowaAdegeye