SlideShare a Scribd company logo
안드로이드 스레드, 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

RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
Dustin Graham
 
Deep dive into Android async operations
Deep dive into Android async operationsDeep dive into Android async operations
Deep dive into Android async operations
Mateusz Grzechociński
 
Android classes in mumbai
Android classes in mumbaiAndroid classes in mumbai
Android classes in mumbai
Vibrant Technologies & Computers
 
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 iOS
TechWell
 
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.JS
Ilia Idakiev
 
Android101
Android101Android101
Android101
David Marques
 
mobl
moblmobl
mobl
zefhemel
 
jsDay 2016 recap
jsDay 2016 recapjsDay 2016 recap
jsDay 2016 recap
Giorgio Cefaro
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
Aaron Stannard
 
Mobile optimization
Mobile optimizationMobile optimization
Mobile optimization
purplecabbage
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for Android
Emanuele Di Saverio
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Web
nickmbailey
 

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

Game Development with Unity3D (Game Development lecture 3)
Game Development  with Unity3D (Game Development lecture 3)Game Development  with Unity3D (Game Development lecture 3)
Game Development with Unity3D (Game Development lecture 3)
abdulrafaychaudhry
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)
abdulrafaychaudhry
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 

Recently uploaded (20)

Game Development with Unity3D (Game Development lecture 3)
Game Development  with Unity3D (Game Development lecture 3)Game Development  with Unity3D (Game Development lecture 3)
Game Development with Unity3D (Game Development lecture 3)
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 

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