SlideShare a Scribd company logo
1 of 82
Download to read offline
ANDROID JETPACK + COROUTINES:
TO INFINITEAND BEYOND
Ramon Ribeiro Rabello
Hi, I’m Ramon Rabello | Bio
11 years in Android
GDG Floripa Organizer
❤ Communities
Star Wars fan, I am!
Master Software Engineer |
about.me/ramonrabello
Beer lover
Come meet us! | ArcTouch Brasil at TDC
"Ask the Experts" Android session
Ramon & Paula - 13:10
Android Dev Generations™
Android Dev Generations | Looking back on Android history
Create Modern Apps with Android Jetpack
2008-2012 2013-2016 2017-…
Android Dev Generations | Looking back on Android history
Create Modern Apps with Android Jetpack
2008-2012 2013-2016 2017-…
Android Dev Generations | Looking back on Android history
Create Modern Apps with Android Jetpack
2008-2012 2013-2016 2017-…
Android Jetpack Recap
Android Jetpack | Overview
Simplify complex tasks
A collection of Android software components
Follow best practices
Free you from writing boilerplate code
Comprises the androidx.* packages
Android Jetpack | Overview
Simplify complex tasks
A collection of Android software components
Follow best practices
Free you from writing boilerplate code
Comprises the androidx.* packages
Android Jetpack | Overview
Simplify complex tasks
A collection of Android software components
Follow best practices
Free you from writing boilerplate code
Comprises the androidx.* packages
Android Jetpack | Overview
Simplify complex tasks
A collection of Android software components
Follow best practices
Free you from writing boilerplate code
Comprises the androidx.* packages
Android Jetpack | Overview
Simplify complex tasks
A collection of Android software components
Follow best practices
Free you from writing boilerplate code
Comprises the androidx.* packages
Android Jetpack | Components
Architecture
Foundation Behaviour
UI
•
Jetpack Components | Foundation
AppCompat
Android KTX
Multidex
Test
Architecture
Foundation Behaviour
UI
•
NEW
Jetpack Components | Architecture
DataBinding
Lifecycles
LiveData
Navigation
Paging
Room
ViewModel
WorkManager
Architecture
Foundation Behaviour
UI
•
NEW
NEW
NEW
Jetpack Components | UI
Animation & transitions
Auto
Emoji
Fragment
Layout
Palette
TV
Wear OS by Google
Architecture
Foundation Behaviour
UI
•
Jetpack Components | Behavior
Download manager
Media & playback
Notifications
Permissions
Sharing
Slices
Architecture
Foundation Behaviour
UI
•
NEW
androidx
androidx | Overview
com.android.support:support-fragment
com.android.support:cardview-v7
com.android.support:recyclerview-v7
androidx | Overview
com.android.support:fragment:support-fragment
com.android.support:cardview:cardview
com.android.support:recyclerview:recyclerview
androidx
androidx
androidx
androidx | Migrating to androidx
Manually
Automagically
Add both androidX=true and enableJetfier=true to
gradle.properties file
In Android Studio 3.2.1+: Refactor -> Migrate to AndroidX…
android-ktx
ANDROIDX.CORE:CORE-KTX
KOTLIN
sharedPreferences.edit()
.putBoolean("key", value)
.apply()
KOTLIN + ANDROID KTX
sharedPreferences.edit {
putBoolean("key", value)
}
KOTLIN
view.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
viewTreeObserver.removeOnPreDrawListener(this)
actionToBeTriggered()
return true
}
}
)
KOTLIN + ANDROID KTX
view.doOnPreDraw {
actionToBeTriggered()
}
Architecture Components
Architecture Components | The Big Picture
Activity/Fragment
LiveData
LiveData
Repository
ViewModel
Local Data Source
Room
Remote Data Source
Retrofit
SQLite API
Architecture Components
Recipes™
Recipe #1 | ViewModel + Rx
Activity/Fragment
Repository
ViewModel
Local Data Source
Room
Remote Data Source
Retrofit
SQLite API
Single<T>
Single<T>
Single<T>
Subject<T>
Recipe #1 | ViewModel + Rx
class TrendingViewModel @Inject constructor(...) : BaseViewModel() {
private val uiStateSubject by lazy { BehaviorSubject<UiState>.create() }
fun loadTrending() {
uiStateSubject.onNext(UiState.Loading)
repository.loadTrending()
.doOnSuccess { trending -> uiStateSubject.onNext(UiState.Loaded(trending)) }
.doOnError { error -> uiStateSubject.onNext(UiState.Error(error)) }
.safeSubscribe()
}
fun observeUiState() : Observable<UiState> = uiStateSubject
}
Recipe #1 | ViewModel + Rx
class TrendingFragment: BaseDaggerFragment() {
fun loadTrending() {
viewModel.observeUiState()
.subscribe(::onUiStateChanged, ::onTrendingError)
fun onUiStateChanged(uiState: UiState){
when(uiState){
is UiState.Loading -> showLoading()
is UiState.Loaded -> showTrending(uiState.trending)
is UiState.Error -> hideLoading()
}
}
}
Recipe #2 | ViewModel + Rx + LiveData
Activity/Fragment
Repository
ViewModel
Local Data Source
Room
Remote Data Source
Retrofit
SQLite API
Single<T>
Single<T>
Single<T>
LiveData
LiveData
Recipe #2 | ViewModel + Rx + LiveData
class TrendingViewModel @Inject constructor(...) : BaseViewModel() {
private val _uiStateEvent = MutableLiveData<UiState>()
val uiStateEvent: LiveData<UiState>
get() = _uiStateEvent
fun loadTrending() {
repository.loadTrending()
.doOnSubscribe { _uiStateEvent.postValue(UiState.Loading) }
.doOnSuccess { _uiStateEvent.postValue(UiState.Loaded(trending)) }
.doOnError { _uiStateEvent.postValue(UiState.Error) }
.safeSubscribe()
}
}
Recipe #2 | ViewModel + LiveData (SingleLiveEvent)
Activity/Fragment
Repository
ViewModel
Local Data Source
Room
Remote Data Source
Retrofit
SQLite API
LiveData
LiveData
LiveData
LiveData
LiveData
Recipe #2 | ViewModel + LiveData (SingleLiveEvent)
class TrendingViewModel @Inject constructor(...) : BaseViewModel() {
private val _uiStateEvent = SingleLiveEvent<UiState>()
val uiStateEvent: LiveData<UiState>
get() = _uiStateEvent
fun loadTrending() {
_uiStateEvent.postValue(UiState.Loading)
val result = Transformations.map(repository.loadTrending()){
_uiStateEvent.postValue(UiState.Loaded(result.value))
}
}
}
Demo Time - Part 1
What players have adopted
Android Jetpack?
Android Jetpack adoption | top apps
What about Coroutines?
Before Coroutines | Ways to do async on Android
AsyncTasks
Loaders
Executors
ThreadPools
Rx
All of them relies onThreads
Coroutines | Brief history
Founded on Continuation principle
Concept first coined in 1958 by Melvin Conway
Like threads, but far away more lightweight
Tasks that can be suspended and resumed
Stable as of Kotlin 1.3
https://github.com/Kotlin/kotlinx.coroutines
Coroutines | Brief history
Founded on Continuation principle
Concept first coined in 1958 by Melvin Conway
Like threads, but far away more lightweight
Tasks that can be suspended and resumed
Stable as of Kotlin 1.3
https://github.com/Kotlin/kotlinx.coroutines
Coroutines | Brief history
Founded on Continuation principle
Concept first coined in 1958 by Melvin Conway
Like threads, but far away more lightweight
Tasks that can be suspended and resumed
Stable as of Kotlin 1.3
https://github.com/Kotlin/kotlinx.coroutines
Coroutines | Brief history
Founded on Continuation principle
Concept first coined in 1958 by Melvin Conway
Like threads, but far away more lightweight
Tasks that can be suspended and resumed
Stable as of Kotlin 1.3
https://github.com/Kotlin/kotlinx.coroutines
Coroutines | Brief history
Founded on Continuation principle
Concept first coined in 1958 by Melvin Conway
Like threads, but far away more lightweight
Tasks that can be suspended and resumed
Stable as of Kotlin 1.3
https://github.com/Kotlin/kotlinx.coroutines
Coroutines | Motivation
object: LoadingTask : AsyncTask() {
override fun doInBackground() {…}
override fun onPostExecute() {…}
}
Coroutines | Motivation
repository.loadTrending()
.flatMap {...}
.doOnEach {...}
.doOnError {...}
.subscribe(
onNext = { ... },
onError = { ... }
)
}
object: LoadingTask : AsyncTask() {
override fun doInBackground() {…}
override fun onPostExecute() {…}
}
Coroutines | Motivation
repository.loadTrending()
.flatMap {...}
.doOnEach {...}
.doOnError {...}
.subscribe(
onNext = { ... },
onError = { ... }
)
}
object: LoadingTask : AsyncTask() {
override fun doInBackground() {…}
override fun onPostExecute() {…}
}
Coroutines | Motivation
Coroutines | Motivation
fun loadTrending() = launch {
_uiStateEvent.postValue(UiState.Loading)
val result = async { /* load trending */ }.await()
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
dependencies {
implementation
“org.jetbrains.kotlinx:kotlinx-coroutines-core:<version>”
implementation
“org.jetbrains.kotlinx:kotlinx-coroutines-android:<version>”
implementation
“org.jetbrains.kotlinx:kotlinx-coroutines-rx2:<version>”
}
Coroutines | Adding dependencies
Coroutines | Building blocks
Coroutine builder
Coroutine context
suspend function
builders to launch a coroutine
coroutine dispatchers
mark a suspension point
Coroutine builder | launch - synchronous coroutine
fun loadTrending() = launch {
_uiStateEvent.postValue(UiState.Loading)
val result = async { repository.loadTrending() }.await()
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Coroutine builder | launch - synchronous coroutine
fun loadTrending() = launch {
_uiStateEvent.postValue(UiState.Loading)
val result = async { repository.loadTrending() }.await()
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
} Job
Coroutine builder | async - Loading coroutines in parallel
fun loadTrending() = launch {
_uiStateEvent.postValue(UiState.Loading)
val local = async { /* load local trending */ }.await()
val remote = async { /* load remote trending */ }.await()
val result = local + remote
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Coroutine builder | async - Loading coroutines in parallel
fun loadTrending() = launch {
_uiStateEvent.postValue(UiState.Loading)
val local = async { /* load local trending */ }.await()
val remote = async { /* load remote trending */ }.await()
val result = local + remote
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Deferred<T>
Deferred<T>
Coroutine context | Dispatchers
Main
IO
Default
Unconfined
UI Contexts
I/O operations
Uses heavy CPU
computation
No need to run on specific
context
Coroutine builder | withContext - Switching contexts
val uiContext: CoroutineContext = Dispatchers.Main
val ioContext: CoroutineContext = Dispatchers.IO
fun loadTrending() = launch(uiContext) {
_uiStateEvent.postValue(UiState.Loading)
val result = withContext(ioContext){ repository.loadTrending() }
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Coroutine builder | withContext - Switching contexts
val uiContext: CoroutineContext = Dispatchers.Main
val ioContext: CoroutineContext = Dispatchers.IO
fun loadTrending() = launch(uiContext) {
_uiStateEvent.postValue(UiState.Loading)
val result = withContext(ioContext){ repository.loadTrending() }
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
parent coroutine
Coroutine builder | withContext - Switching contexts
val uiContext: CoroutineContext = Dispatchers.Main
val ioContext: CoroutineContext = Dispatchers.IO
fun loadTrending() = launch(uiContext) {
_uiStateEvent.postValue(UiState.Loading)
val result = withContext(ioContext){ repository.loadTrending() }
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Child coroutine
parent coroutine
Coroutine builder | withContext - Switching contexts
val uiContext: CoroutineContext = Dispatchers.Main
val ioContext: CoroutineContext = Dispatchers.IO
fun loadTrending() = launch(uiContext) {
_uiStateEvent.postValue(UiState.Loading)
val result = withContext(ioContext){ repository.loadTrending() }
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Child coroutine
parent coroutine
Coroutine builder | withContext - Switching contexts
val uiContext: CoroutineContext = Dispatchers.Main
val ioContext: CoroutineContext = Dispatchers.IO
fun loadTrending() = launch(uiContext) {
_uiStateEvent.postValue(UiState.Loading)
val result = withContext(ioContext){ repository.loadTrending() }
_trendingData.postValue(Result.success(result))
_uiStateEvent.postValue(UiState.Loaded)
}
Child coroutine
parent coroutine
Coroutines | suspending a point of execution
suspend fun loadTrending(){…}
⚠
Suspended coroutines must be called only from other
suspended ones.
Coroutines | suspend - suspending all the things!
suspend fun loadTrending() = trendingApi.loadTrending()
RemoteTrendingDataSource.kt
suspend fun loadTrending() = trendingDao.loadTrending()
LocalTrendingDataSource.kt
suspend fun loadTrending() =
localDataSource.loadTrending().await() +
remoteDataSource.loadTrending().await()
TrendingRepository.kt
fun loadTrending() = launch(uiContext) {
val result = async { repository.loadTrending() }
}
TrendingViewModel.kt
Taking off with Android
Jetpack + Coroutines
Recipe #2 | ViewModel + LiveData + Coroutines
Activity/Fragment
Repository
ViewModel
Local Data Source
Room
Remote Data Source
Retrofit
SQLite API
LiveData
LiveData
Deferred
Deferred Deferred
launch
Adding Coroutines | TrendingApi
interface TrendingApi {
@GET("/v1/gifs/trending")
fun loadTrending(): Deferred<TrendingResponse>
}
Adding Coroutines | ScopedViewModel + Coroutines
open class ScopedViewModel : ViewModel(), CoroutineScope {
override val coroutineContext = Main
protected val jobs = mutableListOf<Job>()
infix fun MutableList<Job>.add(job: Job) { this.add(job) }
override fun onCleared() {
super.onCleared()
jobs.forEach { if(!it.isCancelled) it.cancel() }
}
}
Adding Coroutines | TrendingViewModel
class TrendingViewModel : ScopedViewModel() {
fun loadTrending() {
jobs add launch {
_uiStateEvent.value = UiState.Loading
try {
val result = repository.loadTrending().await()
_uiStateEvent.value = UiState.Loaded(result)
} catch(t: Throwable) {
_uiStateEvent.value = UiState.Error
}
}
}
}
Living Code Time - Part 2
Q: Can Coroutines fully
replace Rx-ish code?
…
ramonrabello/Kiphy
AndroidX
Architecture Components
Material Theming
Coroutines
Dagger 2
Moshi
Kotlin 1.3
What’s next?
What’s next? | Android Jetpack
Modern Android development: Android Jetpack, Kotlin, and more
(Google I/O 2018)
https://www.youtube.com/watch?v=IrMw7MEgADk
Android X | Android Developers
https://developer.android.com/jetpack/androidx/
Android Jetpack | Android Developers
https://developer.android.com/jetpack/
Android KTX | Android Developers
https://developer.android.com/kotlin/ktx
What’s next? | Kotlin Coroutines
Utilizando Kotlin Coroutines no Android | Android Dev BR Medium
https://medium.com/android-dev-br/utilizando-kotlin-coroutines-no-android-
c73fcda71e27
Android Coroutine Recipes
https://developer.android.com/jetpack/androidx/
kotlinx.coroutines GitHub
https://www.github.com/Kotlin/kotlinx.coroutines
Android Suspenders | KotlinConf 2018
https://chris.banes.dev/talks/2018/android-suspenders/
Q & A
THANK YOU.
https://about.me/ramonrabello

More Related Content

What's hot

"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav DukhinFwdays
 
Retrolambda+bolts
Retrolambda+boltsRetrolambda+bolts
Retrolambda+boltsTom Sun
 
React Native in Production
React Native in ProductionReact Native in Production
React Native in ProductionSeokjun Kim
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN GolangBo-Yi Wu
 
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...KAI CHU CHUNG
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...Fwdays
 
Automated acceptance test
Automated acceptance testAutomated acceptance test
Automated acceptance testBryan Liu
 
Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?Tobias Schneck
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionSchalk Cronjé
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You TestSchalk Cronjé
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰KAI CHU CHUNG
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具Shengyou Fan
 
Супер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOSСупер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOSSQALab
 
Drone CI/CD 自動化測試及部署
Drone CI/CD 自動化測試及部署Drone CI/CD 自動化測試及部署
Drone CI/CD 自動化測試及部署Bo-Yi Wu
 
Jetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UIJetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UIGilang Ramadhan
 
Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016Schalk Cronjé
 
PuppetConf 2016: Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
PuppetConf 2016:  Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...PuppetConf 2016:  Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
PuppetConf 2016: Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...Puppet
 
CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)Soshi Nemoto
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術Yuji Hato
 

What's hot (20)

"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
 
Retrolambda+bolts
Retrolambda+boltsRetrolambda+bolts
Retrolambda+bolts
 
React Native in Production
React Native in ProductionReact Native in Production
React Native in Production
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
 
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie..."How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
 
Automated acceptance test
Automated acceptance testAutomated acceptance test
Automated acceptance test
 
Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?Testing - Selenium? Rich-Clients? Containers?
Testing - Selenium? Rich-Clients? Containers?
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具老派浪漫:用 Kotlin 寫 Command Line 工具
老派浪漫:用 Kotlin 寫 Command Line 工具
 
Супер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOSСупер быстрая автоматизация тестирования на iOS
Супер быстрая автоматизация тестирования на iOS
 
Drone CI/CD 自動化測試及部署
Drone CI/CD 自動化測試及部署Drone CI/CD 自動化測試及部署
Drone CI/CD 自動化測試及部署
 
Jetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UIJetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UI
 
Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016
 
PuppetConf 2016: Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
PuppetConf 2016:  Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...PuppetConf 2016:  Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
PuppetConf 2016: Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
 
Tips & Tricks for Maven Tycho
Tips & Tricks for Maven TychoTips & Tricks for Maven Tycho
Tips & Tricks for Maven Tycho
 
CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術
 

Similar to Android Jetpack + Coroutines: To infinity and beyond

React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsMatteo Manchi
 
Session #6 loaders and adapters
Session #6  loaders and adaptersSession #6  loaders and adapters
Session #6 loaders and adaptersVitali Pekelis
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptJohn Stevenson
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotXamarin
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015jbandi
 
Eric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemEric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemGuardSquare
 
Eric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemEric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemGuardSquare
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
UniRx - Reactive Extensions for Unity(EN)
UniRx - Reactive Extensions for Unity(EN)UniRx - Reactive Extensions for Unity(EN)
UniRx - Reactive Extensions for Unity(EN)Yoshifumi Kawai
 
React Native custom components
React Native custom componentsReact Native custom components
React Native custom componentsJeremy Grancher
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupDavid Barreto
 
The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196Mahmoud Samir Fayed
 
reactjs-quiz..docs.pdf
reactjs-quiz..docs.pdfreactjs-quiz..docs.pdf
reactjs-quiz..docs.pdfAyanSarkar78
 
[1D6]RE-view of Android L developer PRE-view
[1D6]RE-view of Android L developer PRE-view[1D6]RE-view of Android L developer PRE-view
[1D6]RE-view of Android L developer PRE-viewNAVER D2
 
React for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectReact for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectAtlassian
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysManuel Bernhardt
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftOleksandr Stepanov
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Roberto Franchini
 

Similar to Android Jetpack + Coroutines: To infinity and beyond (20)

React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applications
 
Session #6 loaders and adapters
Session #6  loaders and adaptersSession #6  loaders and adapters
Session #6 loaders and adapters
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien Pouliot
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015
 
Eric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemEric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build system
 
Eric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemEric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build system
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
UniRx - Reactive Extensions for Unity(EN)
UniRx - Reactive Extensions for Unity(EN)UniRx - Reactive Extensions for Unity(EN)
UniRx - Reactive Extensions for Unity(EN)
 
React Native custom components
React Native custom componentsReact Native custom components
React Native custom components
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
 
The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202
 
The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196
 
reactjs-quiz..docs.pdf
reactjs-quiz..docs.pdfreactjs-quiz..docs.pdf
reactjs-quiz..docs.pdf
 
React native
React nativeReact native
React native
 
[1D6]RE-view of Android L developer PRE-view
[1D6]RE-view of Android L developer PRE-view[1D6]RE-view of Android L developer PRE-view
[1D6]RE-view of Android L developer PRE-view
 
React for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectReact for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence Connect
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
 

More from Ramon Ribeiro Rabello

Ninja Productivity in Android Studio
Ninja Productivity in Android StudioNinja Productivity in Android Studio
Ninja Productivity in Android StudioRamon Ribeiro Rabello
 
Produtividade ninja com android studio
Produtividade ninja com android studioProdutividade ninja com android studio
Produtividade ninja com android studioRamon Ribeiro Rabello
 
Automatize seus testes de UI com a Espresso!
Automatize seus testes de UI com a Espresso!Automatize seus testes de UI com a Espresso!
Automatize seus testes de UI com a Espresso!Ramon Ribeiro Rabello
 
Os caminhos da Agilidade em Empresa Pública
Os caminhos da Agilidade em Empresa PúblicaOs caminhos da Agilidade em Empresa Pública
Os caminhos da Agilidade em Empresa PúblicaRamon Ribeiro Rabello
 
Making your app see with Mobile Vision API
Making your app see with Mobile Vision APIMaking your app see with Mobile Vision API
Making your app see with Mobile Vision APIRamon Ribeiro Rabello
 
Inovar em tempos de crise? Yes, We Can!
Inovar em tempos de crise?  Yes, We Can!Inovar em tempos de crise?  Yes, We Can!
Inovar em tempos de crise? Yes, We Can!Ramon Ribeiro Rabello
 
Android Wear: Estendendo sua app para relógios inteligentes
Android Wear: Estendendo sua app para relógios inteligentesAndroid Wear: Estendendo sua app para relógios inteligentes
Android Wear: Estendendo sua app para relógios inteligentesRamon Ribeiro Rabello
 
O caminho de um desenvolvedor android
O caminho de um desenvolvedor androidO caminho de um desenvolvedor android
O caminho de um desenvolvedor androidRamon Ribeiro Rabello
 
Workshop Android em Ambientes de Integração
Workshop Android em Ambientes de IntegraçãoWorkshop Android em Ambientes de Integração
Workshop Android em Ambientes de IntegraçãoRamon Ribeiro Rabello
 
De idealista à empreendedor - como desenvolver aplicações em android que conq...
De idealista à empreendedor - como desenvolver aplicações em android que conq...De idealista à empreendedor - como desenvolver aplicações em android que conq...
De idealista à empreendedor - como desenvolver aplicações em android que conq...Ramon Ribeiro Rabello
 
Agora é Android, Tá Safo? - #tasafoemacaocastanhal
Agora é Android, Tá Safo? - #tasafoemacaocastanhalAgora é Android, Tá Safo? - #tasafoemacaocastanhal
Agora é Android, Tá Safo? - #tasafoemacaocastanhalRamon Ribeiro Rabello
 

More from Ramon Ribeiro Rabello (20)

Cultura de testes em times mobile
Cultura de testes em times mobileCultura de testes em times mobile
Cultura de testes em times mobile
 
Ninja Productivity in Android Studio
Ninja Productivity in Android StudioNinja Productivity in Android Studio
Ninja Productivity in Android Studio
 
Produtividade ninja com android studio
Produtividade ninja com android studioProdutividade ninja com android studio
Produtividade ninja com android studio
 
Automatize seus testes de UI com a Espresso!
Automatize seus testes de UI com a Espresso!Automatize seus testes de UI com a Espresso!
Automatize seus testes de UI com a Espresso!
 
Os caminhos da Agilidade em Empresa Pública
Os caminhos da Agilidade em Empresa PúblicaOs caminhos da Agilidade em Empresa Pública
Os caminhos da Agilidade em Empresa Pública
 
Making your app see with Mobile Vision API
Making your app see with Mobile Vision APIMaking your app see with Mobile Vision API
Making your app see with Mobile Vision API
 
Inovar em tempos de crise? Yes, We Can!
Inovar em tempos de crise?  Yes, We Can!Inovar em tempos de crise?  Yes, We Can!
Inovar em tempos de crise? Yes, We Can!
 
O ecossistema android
O ecossistema androidO ecossistema android
O ecossistema android
 
Android Marshmallow na prática
Android Marshmallow na práticaAndroid Marshmallow na prática
Android Marshmallow na prática
 
Android Wear: Estendendo sua app para relógios inteligentes
Android Wear: Estendendo sua app para relógios inteligentesAndroid Wear: Estendendo sua app para relógios inteligentes
Android Wear: Estendendo sua app para relógios inteligentes
 
Introdução ao Android Studio
Introdução ao Android StudioIntrodução ao Android Studio
Introdução ao Android Studio
 
O caminho de um desenvolvedor android
O caminho de um desenvolvedor androidO caminho de um desenvolvedor android
O caminho de um desenvolvedor android
 
Criando Apps Sociais em Android
Criando Apps Sociais em AndroidCriando Apps Sociais em Android
Criando Apps Sociais em Android
 
Porque Aprender Android
Porque Aprender AndroidPorque Aprender Android
Porque Aprender Android
 
Workshop Android em Ambientes de Integração
Workshop Android em Ambientes de IntegraçãoWorkshop Android em Ambientes de Integração
Workshop Android em Ambientes de Integração
 
De idealista à empreendedor - como desenvolver aplicações em android que conq...
De idealista à empreendedor - como desenvolver aplicações em android que conq...De idealista à empreendedor - como desenvolver aplicações em android que conq...
De idealista à empreendedor - como desenvolver aplicações em android que conq...
 
Desenvolvimento Web para Android
Desenvolvimento Web para AndroidDesenvolvimento Web para Android
Desenvolvimento Web para Android
 
Agora é Android, Tá Safo? - #tasafoemacaocastanhal
Agora é Android, Tá Safo? - #tasafoemacaocastanhalAgora é Android, Tá Safo? - #tasafoemacaocastanhal
Agora é Android, Tá Safo? - #tasafoemacaocastanhal
 
Boas Práticas em Android
Boas Práticas em AndroidBoas Práticas em Android
Boas Práticas em Android
 
"Facebookoid"
"Facebookoid""Facebookoid"
"Facebookoid"
 

Recently uploaded

CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceanilsa9823
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRnishacall1
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceanilsa9823
 
9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7Pooja Nehwal
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceDelhi Call girls
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Pooja Nehwal
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPsychicRuben LoveSpells
 

Recently uploaded (7)

CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
 
9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
 

Android Jetpack + Coroutines: To infinity and beyond

  • 1. ANDROID JETPACK + COROUTINES: TO INFINITEAND BEYOND Ramon Ribeiro Rabello
  • 2. Hi, I’m Ramon Rabello | Bio 11 years in Android GDG Floripa Organizer ❤ Communities Star Wars fan, I am! Master Software Engineer | about.me/ramonrabello Beer lover
  • 3. Come meet us! | ArcTouch Brasil at TDC "Ask the Experts" Android session Ramon & Paula - 13:10
  • 5. Android Dev Generations | Looking back on Android history Create Modern Apps with Android Jetpack 2008-2012 2013-2016 2017-…
  • 6. Android Dev Generations | Looking back on Android history Create Modern Apps with Android Jetpack 2008-2012 2013-2016 2017-…
  • 7. Android Dev Generations | Looking back on Android history Create Modern Apps with Android Jetpack 2008-2012 2013-2016 2017-…
  • 9. Android Jetpack | Overview Simplify complex tasks A collection of Android software components Follow best practices Free you from writing boilerplate code Comprises the androidx.* packages
  • 10. Android Jetpack | Overview Simplify complex tasks A collection of Android software components Follow best practices Free you from writing boilerplate code Comprises the androidx.* packages
  • 11. Android Jetpack | Overview Simplify complex tasks A collection of Android software components Follow best practices Free you from writing boilerplate code Comprises the androidx.* packages
  • 12. Android Jetpack | Overview Simplify complex tasks A collection of Android software components Follow best practices Free you from writing boilerplate code Comprises the androidx.* packages
  • 13. Android Jetpack | Overview Simplify complex tasks A collection of Android software components Follow best practices Free you from writing boilerplate code Comprises the androidx.* packages
  • 14. Android Jetpack | Components Architecture Foundation Behaviour UI •
  • 15. Jetpack Components | Foundation AppCompat Android KTX Multidex Test Architecture Foundation Behaviour UI • NEW
  • 16. Jetpack Components | Architecture DataBinding Lifecycles LiveData Navigation Paging Room ViewModel WorkManager Architecture Foundation Behaviour UI • NEW NEW NEW
  • 17. Jetpack Components | UI Animation & transitions Auto Emoji Fragment Layout Palette TV Wear OS by Google Architecture Foundation Behaviour UI •
  • 18. Jetpack Components | Behavior Download manager Media & playback Notifications Permissions Sharing Slices Architecture Foundation Behaviour UI • NEW
  • 22. androidx | Migrating to androidx Manually Automagically Add both androidX=true and enableJetfier=true to gradle.properties file In Android Studio 3.2.1+: Refactor -> Migrate to AndroidX…
  • 26. KOTLIN + ANDROID KTX sharedPreferences.edit { putBoolean("key", value) }
  • 27. KOTLIN view.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { viewTreeObserver.removeOnPreDrawListener(this) actionToBeTriggered() return true } } )
  • 28. KOTLIN + ANDROID KTX view.doOnPreDraw { actionToBeTriggered() }
  • 30. Architecture Components | The Big Picture Activity/Fragment LiveData LiveData Repository ViewModel Local Data Source Room Remote Data Source Retrofit SQLite API
  • 32. Recipe #1 | ViewModel + Rx Activity/Fragment Repository ViewModel Local Data Source Room Remote Data Source Retrofit SQLite API Single<T> Single<T> Single<T> Subject<T>
  • 33. Recipe #1 | ViewModel + Rx class TrendingViewModel @Inject constructor(...) : BaseViewModel() { private val uiStateSubject by lazy { BehaviorSubject<UiState>.create() } fun loadTrending() { uiStateSubject.onNext(UiState.Loading) repository.loadTrending() .doOnSuccess { trending -> uiStateSubject.onNext(UiState.Loaded(trending)) } .doOnError { error -> uiStateSubject.onNext(UiState.Error(error)) } .safeSubscribe() } fun observeUiState() : Observable<UiState> = uiStateSubject }
  • 34. Recipe #1 | ViewModel + Rx class TrendingFragment: BaseDaggerFragment() { fun loadTrending() { viewModel.observeUiState() .subscribe(::onUiStateChanged, ::onTrendingError) fun onUiStateChanged(uiState: UiState){ when(uiState){ is UiState.Loading -> showLoading() is UiState.Loaded -> showTrending(uiState.trending) is UiState.Error -> hideLoading() } } }
  • 35. Recipe #2 | ViewModel + Rx + LiveData Activity/Fragment Repository ViewModel Local Data Source Room Remote Data Source Retrofit SQLite API Single<T> Single<T> Single<T> LiveData LiveData
  • 36. Recipe #2 | ViewModel + Rx + LiveData class TrendingViewModel @Inject constructor(...) : BaseViewModel() { private val _uiStateEvent = MutableLiveData<UiState>() val uiStateEvent: LiveData<UiState> get() = _uiStateEvent fun loadTrending() { repository.loadTrending() .doOnSubscribe { _uiStateEvent.postValue(UiState.Loading) } .doOnSuccess { _uiStateEvent.postValue(UiState.Loaded(trending)) } .doOnError { _uiStateEvent.postValue(UiState.Error) } .safeSubscribe() } }
  • 37. Recipe #2 | ViewModel + LiveData (SingleLiveEvent) Activity/Fragment Repository ViewModel Local Data Source Room Remote Data Source Retrofit SQLite API LiveData LiveData LiveData LiveData LiveData
  • 38. Recipe #2 | ViewModel + LiveData (SingleLiveEvent) class TrendingViewModel @Inject constructor(...) : BaseViewModel() { private val _uiStateEvent = SingleLiveEvent<UiState>() val uiStateEvent: LiveData<UiState> get() = _uiStateEvent fun loadTrending() { _uiStateEvent.postValue(UiState.Loading) val result = Transformations.map(repository.loadTrending()){ _uiStateEvent.postValue(UiState.Loaded(result.value)) } } }
  • 39. Demo Time - Part 1
  • 40. What players have adopted Android Jetpack?
  • 43. Before Coroutines | Ways to do async on Android AsyncTasks Loaders Executors ThreadPools Rx
  • 44. All of them relies onThreads
  • 45. Coroutines | Brief history Founded on Continuation principle Concept first coined in 1958 by Melvin Conway Like threads, but far away more lightweight Tasks that can be suspended and resumed Stable as of Kotlin 1.3 https://github.com/Kotlin/kotlinx.coroutines
  • 46. Coroutines | Brief history Founded on Continuation principle Concept first coined in 1958 by Melvin Conway Like threads, but far away more lightweight Tasks that can be suspended and resumed Stable as of Kotlin 1.3 https://github.com/Kotlin/kotlinx.coroutines
  • 47. Coroutines | Brief history Founded on Continuation principle Concept first coined in 1958 by Melvin Conway Like threads, but far away more lightweight Tasks that can be suspended and resumed Stable as of Kotlin 1.3 https://github.com/Kotlin/kotlinx.coroutines
  • 48. Coroutines | Brief history Founded on Continuation principle Concept first coined in 1958 by Melvin Conway Like threads, but far away more lightweight Tasks that can be suspended and resumed Stable as of Kotlin 1.3 https://github.com/Kotlin/kotlinx.coroutines
  • 49. Coroutines | Brief history Founded on Continuation principle Concept first coined in 1958 by Melvin Conway Like threads, but far away more lightweight Tasks that can be suspended and resumed Stable as of Kotlin 1.3 https://github.com/Kotlin/kotlinx.coroutines
  • 50. Coroutines | Motivation object: LoadingTask : AsyncTask() { override fun doInBackground() {…} override fun onPostExecute() {…} }
  • 51. Coroutines | Motivation repository.loadTrending() .flatMap {...} .doOnEach {...} .doOnError {...} .subscribe( onNext = { ... }, onError = { ... } ) } object: LoadingTask : AsyncTask() { override fun doInBackground() {…} override fun onPostExecute() {…} }
  • 52. Coroutines | Motivation repository.loadTrending() .flatMap {...} .doOnEach {...} .doOnError {...} .subscribe( onNext = { ... }, onError = { ... } ) } object: LoadingTask : AsyncTask() { override fun doInBackground() {…} override fun onPostExecute() {…} }
  • 54. Coroutines | Motivation fun loadTrending() = launch { _uiStateEvent.postValue(UiState.Loading) val result = async { /* load trending */ }.await() _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) }
  • 56. Coroutines | Building blocks Coroutine builder Coroutine context suspend function builders to launch a coroutine coroutine dispatchers mark a suspension point
  • 57. Coroutine builder | launch - synchronous coroutine fun loadTrending() = launch { _uiStateEvent.postValue(UiState.Loading) val result = async { repository.loadTrending() }.await() _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) }
  • 58. Coroutine builder | launch - synchronous coroutine fun loadTrending() = launch { _uiStateEvent.postValue(UiState.Loading) val result = async { repository.loadTrending() }.await() _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) } Job
  • 59. Coroutine builder | async - Loading coroutines in parallel fun loadTrending() = launch { _uiStateEvent.postValue(UiState.Loading) val local = async { /* load local trending */ }.await() val remote = async { /* load remote trending */ }.await() val result = local + remote _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) }
  • 60. Coroutine builder | async - Loading coroutines in parallel fun loadTrending() = launch { _uiStateEvent.postValue(UiState.Loading) val local = async { /* load local trending */ }.await() val remote = async { /* load remote trending */ }.await() val result = local + remote _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) } Deferred<T> Deferred<T>
  • 61. Coroutine context | Dispatchers Main IO Default Unconfined UI Contexts I/O operations Uses heavy CPU computation No need to run on specific context
  • 62. Coroutine builder | withContext - Switching contexts val uiContext: CoroutineContext = Dispatchers.Main val ioContext: CoroutineContext = Dispatchers.IO fun loadTrending() = launch(uiContext) { _uiStateEvent.postValue(UiState.Loading) val result = withContext(ioContext){ repository.loadTrending() } _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) }
  • 63. Coroutine builder | withContext - Switching contexts val uiContext: CoroutineContext = Dispatchers.Main val ioContext: CoroutineContext = Dispatchers.IO fun loadTrending() = launch(uiContext) { _uiStateEvent.postValue(UiState.Loading) val result = withContext(ioContext){ repository.loadTrending() } _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) } parent coroutine
  • 64. Coroutine builder | withContext - Switching contexts val uiContext: CoroutineContext = Dispatchers.Main val ioContext: CoroutineContext = Dispatchers.IO fun loadTrending() = launch(uiContext) { _uiStateEvent.postValue(UiState.Loading) val result = withContext(ioContext){ repository.loadTrending() } _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) } Child coroutine parent coroutine
  • 65. Coroutine builder | withContext - Switching contexts val uiContext: CoroutineContext = Dispatchers.Main val ioContext: CoroutineContext = Dispatchers.IO fun loadTrending() = launch(uiContext) { _uiStateEvent.postValue(UiState.Loading) val result = withContext(ioContext){ repository.loadTrending() } _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) } Child coroutine parent coroutine
  • 66. Coroutine builder | withContext - Switching contexts val uiContext: CoroutineContext = Dispatchers.Main val ioContext: CoroutineContext = Dispatchers.IO fun loadTrending() = launch(uiContext) { _uiStateEvent.postValue(UiState.Loading) val result = withContext(ioContext){ repository.loadTrending() } _trendingData.postValue(Result.success(result)) _uiStateEvent.postValue(UiState.Loaded) } Child coroutine parent coroutine
  • 67. Coroutines | suspending a point of execution suspend fun loadTrending(){…} ⚠ Suspended coroutines must be called only from other suspended ones.
  • 68. Coroutines | suspend - suspending all the things! suspend fun loadTrending() = trendingApi.loadTrending() RemoteTrendingDataSource.kt suspend fun loadTrending() = trendingDao.loadTrending() LocalTrendingDataSource.kt suspend fun loadTrending() = localDataSource.loadTrending().await() + remoteDataSource.loadTrending().await() TrendingRepository.kt fun loadTrending() = launch(uiContext) { val result = async { repository.loadTrending() } } TrendingViewModel.kt
  • 69. Taking off with Android Jetpack + Coroutines
  • 70. Recipe #2 | ViewModel + LiveData + Coroutines Activity/Fragment Repository ViewModel Local Data Source Room Remote Data Source Retrofit SQLite API LiveData LiveData Deferred Deferred Deferred launch
  • 71. Adding Coroutines | TrendingApi interface TrendingApi { @GET("/v1/gifs/trending") fun loadTrending(): Deferred<TrendingResponse> }
  • 72. Adding Coroutines | ScopedViewModel + Coroutines open class ScopedViewModel : ViewModel(), CoroutineScope { override val coroutineContext = Main protected val jobs = mutableListOf<Job>() infix fun MutableList<Job>.add(job: Job) { this.add(job) } override fun onCleared() { super.onCleared() jobs.forEach { if(!it.isCancelled) it.cancel() } } }
  • 73. Adding Coroutines | TrendingViewModel class TrendingViewModel : ScopedViewModel() { fun loadTrending() { jobs add launch { _uiStateEvent.value = UiState.Loading try { val result = repository.loadTrending().await() _uiStateEvent.value = UiState.Loaded(result) } catch(t: Throwable) { _uiStateEvent.value = UiState.Error } } } }
  • 74. Living Code Time - Part 2
  • 75. Q: Can Coroutines fully replace Rx-ish code?
  • 76.
  • 79. What’s next? | Android Jetpack Modern Android development: Android Jetpack, Kotlin, and more (Google I/O 2018) https://www.youtube.com/watch?v=IrMw7MEgADk Android X | Android Developers https://developer.android.com/jetpack/androidx/ Android Jetpack | Android Developers https://developer.android.com/jetpack/ Android KTX | Android Developers https://developer.android.com/kotlin/ktx
  • 80. What’s next? | Kotlin Coroutines Utilizando Kotlin Coroutines no Android | Android Dev BR Medium https://medium.com/android-dev-br/utilizando-kotlin-coroutines-no-android- c73fcda71e27 Android Coroutine Recipes https://developer.android.com/jetpack/androidx/ kotlinx.coroutines GitHub https://www.github.com/Kotlin/kotlinx.coroutines Android Suspenders | KotlinConf 2018 https://chris.banes.dev/talks/2018/android-suspenders/
  • 81. Q & A