Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Coroutines And Flow
Search
José Caique Oliveira
June 15, 2019
Technology
2
110
Coroutines And Flow
An introduction to Kotlin Coroutines and Flow apis
José Caique Oliveira
June 15, 2019
Tweet
Share
More Decks by José Caique Oliveira
See All by José Caique Oliveira
Kotlin Flow
jcaiqueoliveira
0
110
Testing your app
jcaiqueoliveira
0
290
Modularizando seu app
jcaiqueoliveira
0
71
Nova Api de Localização Android
jcaiqueoliveira
0
83
Arquitetura para android
jcaiqueoliveira
6
320
Kotlin por onde começar?
jcaiqueoliveira
1
90
Introdução ao Android
jcaiqueoliveira
1
81
Arquitetura para projetos Android
jcaiqueoliveira
1
230
Kotlin 1.1
jcaiqueoliveira
0
130
Other Decks in Technology
See All in Technology
AIエージェントで90秒の広告動画を制作!台本・音声・映像・編集をつなぐAWS最新アーキテクチャの実践
nasuvitz
3
350
開発者を支える Internal Developer Portal のイマとコレカラ / To-day and To-morrow of Internal Developer Portals: Supporting Developers
aoto
PRO
1
480
COVESA VSSによる車両データモデルの標準化とAWS IoT FleetWiseの活用
osawa
1
390
「どこから読む?」コードとカルチャーに最速で馴染むための実践ガイド
zozotech
PRO
0
560
Codeful Serverless / 一人運用でもやり抜く力
_kensh
7
450
エンジニアリングマネージャーの成長の道筋とキャリア / Developers Summit 2025 KANSAI
daiksy
3
1k
プラットフォーム転換期におけるGitHub Copilot活用〜Coding agentがそれを加速するか〜 / Leveraging GitHub Copilot During Platform Transition Periods
aeonpeople
1
230
Aurora DSQLはサーバーレスアーキテクチャの常識を変えるのか
iwatatomoya
1
1.2k
slog.Handlerのよくある実装ミス
sakiengineer
4
470
MagicPod導入から半年、オープンロジQAチームで実際にやったこと
tjoko
0
110
初めてAWSを使うときのセキュリティ覚書〜初心者支部編〜
cmusudakeisuke
1
280
Generative AI Japan 第一回生成AI実践研究会「AI駆動開発の現在地──ブレイクスルーの鍵を握るのはデータ領域」
shisyu_gaku
0
330
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.6k
Visualization
eitanlees
148
16k
Embracing the Ebb and Flow
colly
87
4.8k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
The Cult of Friendly URLs
andyhume
79
6.6k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Designing for Performance
lara
610
69k
Bash Introduction
62gerente
615
210k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Git: the NoSQL Database
bkeepers
PRO
431
66k
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.8k
Speed Design
sergeychernyshev
32
1.1k
Transcript
COROUTINES AND FLOW JOSÉ CAIQUE
PROGRAM PROCESS THREADS
A PROGRAM IS A SET OF OPERATIONS TO A COMPUTER
TO PERFORM. A COMPUTER PROGRAM BECOMES A PROCESS WHEN IT IS LOADED AND BEGINS EXECUTION
A THREAD IS A SEQUENCE OF SUCH INSTRUCTIONS WITH A
PROGRAM THAT CAN BE EXECUTED INDEPENDENTLY OF OTHER CODE
COROUTINES
ESSENTIALLY, COROUTINES ARE LIGHT- WEIGHT THREADS
fun main() = runBlocking { val jobs = List(100_000) {
launch { delay(1000L) print(".") } } jobs.forEach { it.join() } } java.lang.OutOfMemoryError fun main() { val jobs = List(100_000) { thread { sleep(1000L) print(".") } } jobs.forEach { it.join() } } COROUTINES THREADS
DISPATCHERS
WHICH THREAD WILL LAUNCH THE COROUTINE
- DISPATCHERS.MAIN (ANDROID ONLY) - DISPATCHERS.DEFAULT - DISPATCHERS.IO - DISPATCHERS.UNCONFINED
fun main() { GlobalScope.launch(Main) {} GlobalScope.launch(IO) {} GlobalScope.launch(Main) {} GlobalScope.launch(Unconfined)
{} GlobalScope.launch(newSingleThreadContext("myContext")) {} }
SCOPES
DEFINE A SCOPE FOR NEW COROUTINES. USED TO PROPAGATE THE
ELEMENTS AND CANCELLATION
class MyActivity : Activity(), CoroutineScope by MainScope() { override fun
onDestroy() { cancel() } } class MyViewModel : ViewModel(), CoroutineScope { override val coroutineContext: CoroutineContext = Main override fun onCleared() { super.onCleared() cancel() } } class MyViewModel : ViewModel() { init { viewModelScope.launch { ... } } }
SUSPEND FUNCTION
EXECUTION OF THE CODE WITHOUT BLOCKING THE CURRENT THREAD OF
EXECUTION. A SUSPENDING FUNCTION CANNOT BE INVOKED FROM A REGULAR CODE, BUT ONLY FROM OTHER SUSPENDING FUNCTIONS AND FROM SUSPENDING LAMBDAS
SUSPENDING FUNCTIONS DO NOT BLOCK THE CALLER THREAD. SUSPENDING FUNCTIONS
HAVE THE ABILITY TO BLOCK THE EXECUTION OF THE COROUTINE
suspend fun doRequest() : Int { return 1 } suspend
fun doRequest(): Int = withContext(IO) { 1 } //withTimeout(1000L){ ... }
suspend fun listFromApi(){ viewState.value = ScreenState.Loading viewState.value = ScreenState.Result(performRequest()) }
suspend fun doRequest(): Int = withContext(IO) { 1 }
fun retrieve() : Int { doRequest() } suspend fun doRequest():
Int = withContext(IO) { 1 //some result here } Suspend function 'performRequest' should be called only from a coroutine or another suspend function
BUILDERS
THE WAYS TO RUN A NEW COROUTINE
runBlocking{ viewState.value = ScreenState.Loading viewState.value = performRequest() } @Test fun
testSuspendingFunction() = runBlocking { val res = suspendingTask1() assertEquals(0, res) }
val job : Job = viewModelScope.launch{ viewState.value = ScreenState.Loading viewState.value
= performRequest() } //job.cancel()
val result : Deferred<T> = viewModelScope.async { viewState.value = ScreenState.Loading
viewState.value = performRequest() } result.await() //blocking result.cancel()
viewModelScope.launch(Main) { val user = withContext(IO) { userService.doLogin(username, password) }
val currentFriends = withContext(IO) { userService.requestCurrentFriends(user) } val suggestedFriends = withContext(IO) { userService.requestSuggestedFriends(user) } val finalUser = user.copy( friends = currentFriends + suggestedFriends) }
viewModelScope.launch(Main) { val user = withContext(IO) { userService.doLogin(username, password) }
val currentFriends = async(IO) { userService.requestCurrentFriends(user) } val suggestedFriends = async(IO) { userService.requestSuggestedFriends(user) } val finalUser = user.copy( friends = currentFriends + suggestedFriends) }
REMOVING CALLBACKS
suspend fun login(name: String, psw: String): User = suspendCancellableCoroutine {
continuation -> service.doLogin(username, password) { user -> continuation.resume(user) } } //continuation.resumeWithException(error)
FLOW
KOTLIN REACTIVE PROGRAMMING COLD STREAMS + COROUTINES + OPERATORS SIMILAR
TO SEQUENCES, FLOWS CAN BE TRANSFORMED USING VARIOUS COMMON OPERATORS LIKE MAP, FILTER, ETC UNLIKE A SEQUENCE, A FLOW IS ASYNCHRONOUS AND ALLOWS SUSPENDING FUNCTIONS ANYWHERE IN ITS BUILDER AND OPERATORS
fun foo(p: Params): Flow<Value> = flow { while (hasMore) emit(nextValue)
} val ints: Flow<Int> = flow { for (i in 1..10) { delay(100) emit(i) } } ints.collect { println(it) }
fun <T> Flow<T>.delayASecond() = flow { collect { value ->
// collect from the original flow delay(1000) // delay 1 second emit(value) // emit value to the resulting flow } }
YOU CAN EASILY CREATE YOUR OWN OPERATOR
val broadcast: ConflatedBroadcastChannel<User> // emitting launch { broadcast.send(mMap.getBounds()) } //
listening broadcast.consumeEach { service .retrieve(it) .map { it.getOrNull() } .collect { it?.let { … } } } //close broadcast.close()
JOSÉ CAIQUE ▸ Software Engineer ▸ Computer Science by UFS
▸ Android Tech Lead at Stone ▸ Speaker
J C A I Q U E _ J O
S E C A I Q U E J O S E C A I Q U E T H A N K S
REFERENCES ▸ http://www.inf.puc-rio.br/~roberto/docs/MCC15-04.pdf ▸ https://searchsoftwarequality.techtarget.com/definition/program ▸ https://stackoverflow.com/questions/43021816/difference-between-thread- and-coroutine-in-kotlin ▸ https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md
▸ https://kotlinlang.org/docs/reference/coroutines/basics.html ▸ https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055 ▸ https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/ kotlinx.coroutines/-coroutine-scope/ ▸ https://skillsmatter.com/skillscasts/12727-coroutines-by- example#showModal?modal-signup-complete ▸ https://antonioleiva.com/coroutines/ ▸ https://sourcediving.com/kotlin-coroutines-in-android-e2d5bb02c275 ▸ https://medium.com/@elizarov/simple-design-of-kotlin-flow-4725e7398c4c