SlideShare uma empresa Scribd logo
1 de 90
Baixar para ler offline
Async code on Kotlin:
RxJava or/and coroutines
Fabio Collini
Milan | November 29 - 30, 2018
@fabioCollini
linkedin.com/in/fabiocollini
github.com/fabioCollini
medium.com/@fabioCollini
codingjam.it
Android programmazione
avanzata
Android Developers Italia
Ego slide
Single
Maybe
Completable
Observable
Flowable
Cold Vs Hot
Subjects
suspend methods
Job/Deferred
Channels
Actors
Producers
Publishers
BroadcastChannels
RxJava Coroutines
Single
Maybe
Completable
Observable
Flowable
Cold Vs Hot
Subjects
suspend methods
Job/Deferred
Channels
Actors
Producers
Publishers
BroadcastChannels
RxJava Coroutines
RxJava
Coroutines
OR
RxJava
Coroutines
AND
CompletableSource.await, MaybeSource.await, MaybeSource.awaitOrDefault,
MaybeSource.openSubscription, SingleSource.await,
ObservableSource.awaitFirst, ObservableSource.awaitFirstOrDefault,
ObservableSource.awaitFirstOrElse, ObservableSource.awaitFirstOrNull,
ObservableSource.awaitLast, ObservableSource.awaitSingle,
ObservableSource.openSubscription, ObservableSource.iterator
RxJava Coroutines->RxJava Coroutines->
RxJava Coroutines->
RxJavaCoroutines->
rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable
CompletableSource.await, MaybeSource.await, MaybeSource.awaitOrDefault,
MaybeSource.openSubscription, SingleSource.await,
ObservableSource.awaitFirst, ObservableSource.awaitFirstOrDefault,
ObservableSource.awaitFirstOrElse, ObservableSource.awaitFirstOrNull,
ObservableSource.awaitLast, ObservableSource.awaitSingle,
ObservableSource.openSubscription, ObservableSource.iterator
github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2
github.com/fabioCollini/
RxJavaVsCoroutines
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Single<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Single<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Single<List<Tag>>
}0
RxJava
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Single<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Single<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Single<List<Tag>>
}0
interface StackOverflowService {
@GET("/users")suspend
fun getTopUsers(): Deferred<List<User>>
@GET("/users/{userId}/badges")suspend
fun getBadges(
@Path("userId") userId: Int
): Deferred<List<Badge>>
@GET("/users/{userId}/top-tags")suspend
fun getTags(
@Path("userId") userId: Int
): Deferred<List<Tag>>
}1
RxJava Coroutines
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Single<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Single<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Single<List<Tag>>
}0
interface StackOverflowService {
@GET("/users")suspend
fun getTopUsers(): Deferred<List<User>>
@GET("/users/{userId}/badges")suspend
fun getBadges(
@Path("userId") userId: Int
): Deferred<List<Badge>>
@GET("/users/{userId}/top-tags")suspend
fun getTags(
@Path("userId") userId: Int
): Deferred<List<Tag>>
}1
RxJava Coroutines
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Single<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Single<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Single<List<Tag>>
}0
RxJava Coroutines
interface StackOverflowService {
@GET("/users")suspend
fun getTopUsers(): Deferred<List<User>>
@GET("/users/{userId}/badges")suspend
fun getBadges(
@Path("userId") userId: Int
): Deferred<List<Badge>>
@GET("/users/{userId}/top-tags")suspend
fun getTags(
@Path("userId") userId: Int
): Deferred<List<Tag>>
}1
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Single<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Single<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Single<List<Tag>>
}0
interface StackOverflowService {
@GET("/users")
suspend fun getTopUsers(): List<User>
@GET("/users/{userId}/badges")
suspend fun getBadges(
@Path("userId") userId: Int
): List<Badge>
@GET("/users/{userId}/top-tags")
suspend fun getTags(
@Path("userId") userId: Int
): List<Tag>
}1
RxJava Coroutines
https://github.com/square/retrofit/pull/2886
service.getTopUsers()
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
RxJava
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
RxJava
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
RxJava Coroutines
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
Coroutines
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
Coroutines
suspend fun getTopUsers(): List<User>
GlobalScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}
Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
RxJava Coroutines
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
private val disposable = CompositeDisposable()
fun load() {
disposable +=
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
}A
private fun updateUi(s: Any) {
//...
}B
override fun onCleared() {
disposable.clear()
}C
}D
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
fun load() {
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
}E
private fun updateUi(s: Any) {
//...
}G
}H
RxJava Coroutines
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
private val disposable = CompositeDisposable()
fun load() {
disposable +=
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
}A
private fun updateUi(s: Any) {
//...
}B
override fun onCleared() {
disposable.clear()
}C
}D
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
fun load() {
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
}E
private fun updateUi(s: Any) {
//...
}G
}H
RxJava Coroutines
viewModelScope
viewModelScope
Uses Dispatchers.Main
doesn’t block the Main thread executing a suspending method
Connected to the ViewModel lifecycle
cancels the Jobs when the ViewModel is destroyed
not available yet (but easy to implement)
android-review.googlesource.com/c/platform/frameworks/support/+/772083
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
private val disposable = CompositeDisposable()
fun load() {
disposable +=
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
}A
private fun updateUi(s: Any) {
//...
}B
override fun onCleared() {
disposable.clear()
}C
}D
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
fun load() {
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
}E
private fun updateUi(s: Any) {
//...
}G
}H
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val users = service.getTopUsers()
val firstUser = users.first()
val badges = service.getBadges(firstUser.id)
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
updateUi("loading users")
service.getTopUsers()
.observeOn(mainThread())
.doOnSuccess { updateUi("loading badges") }
.observeOn(io())
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
updateUi("loading users")
val users = service.getTopUsers()
updateUi("loading badges")
val firstUser = users.first()
val badges = service.getBadges(firstUser.id)
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val users = service.getTopUsers()
val firstUser = users.first()
val badges = service.getBadges(firstUser.id)
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val badges = withContext(IO) {
val users = service.getTopUsers()
val firstUser = users.first()
service.getBadges(firstUser.id)
}3
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
RxJava Coroutines
Schedulers
subscribeOn defines
when the computation
starts
observeOn changes the
thread (until next
observeOn)
Dispatchers
the computation starts on
the context dispatcher
withContext changes the
thread in a block
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val badges = withContext(IO) {
val users = service.getTopUsers()
val firstUser = users.first()
service.getBadges(firstUser.id)
}3
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
.map { badges ->
UserStats(firstUser, badges)
}p
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_userWithBadges_->_
updateUi(userWithBadges)
},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val userWithBadges = withContext(IO) {
val users = service.getTopUsers()
val firstUser = users.first()
val badges = service.getBadges(
firstUser.id)
UserStats(firstUser, badges)
}3
updateUi(userWithBadges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
RxJava
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_user_->_
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
}0
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
.toObservable()
}0
.toList()
RxJava
Coroutines
viewModelScope.launch {
try {
val userWithBadges = withContext(IO) {
val users = service.getTopUsers()
val firstUser = users.first()
val badges = service.getBadges(
firstUser.id)
UserStats(firstUser, badges)
}3
updateUi(userWithBadges)
} catch (e: Exception) {
updateUi(e)
}4
}5
viewModelScope.launch {
try {
val usersWithBadges = withContext(IO) {
service.getTopUsers()
.take(5)
.map { user ->
UserStats(user,
service.getBadges(user.id))
}2
}3
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
Coroutines
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ usersWithBadges ->
updateUi(usersWithBadges)
},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val usersWithBadges = withContext(IO) {
service.getTopUsers()
.take(5)
.map { user ->
UserStats(user,
service.getBadges(user.id))
}2
}3
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
.subscribeOn(io())
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ usersWithBadges ->
updateUi(usersWithBadges)
},
{ e -> updateUi(e) }
)1
RxJava Coroutines
viewModelScope.launch {
try {
val usersWithBadges = withContext(IO) {
service.getTopUsers()
.take(5)
.map { user ->
UserStats(user,
service.getBadges(user.id))
}2
}3
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
.subscribeOn(io())
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ usersWithBadges ->
updateUi(usersWithBadges)
},
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val usersWithBadges = withContext(IO) {
service.getTopUsers()
.take(5)
.map { user ->
async {
UserStats(user,
service.getBadges(user.id))
}
}2
.map { it.await() }
}3
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
userDetail(user)
.subscribeOn(io())
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users ->
updateUi(users)
},
{ e -> updateUi(e) }
)1
fun userDetail(user: User): Single<UserStats> {
return service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}7
}8
RxJava Coroutines
viewModelScope.launch {
try {
val usersWithBadges = withContext(IO) {
service.getTopUsers()
.take(5)
.map { user ->
async {
UserStats(user,
service.getBadges(user.id))
}
}2
.map { it.await() }
}3
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
userDetail(user)
.subscribeOn(io())
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users ->
updateUi(users)
},
{ e -> updateUi(e) }
)1
fun userDetail(user: User): Single<UserStats> {
return service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}7
}8
viewModelScope.launch {
try {
val usersWithBadges = withContext(IO) {
service.getTopUsers()
.take(5)
.map { user ->
async {
userDetail(user)
}
}2
.map { it.await() }
}3
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
suspend fun userDetail(user: User): UserStats {
return UserStats(user,
service.getBadges(user.id))
}9
RxJava Coroutines
fun userDetail(user: User): Single<UserStats> {
return service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}7
}8
suspend fun userDetail(user: User): UserStats {
return UserStats(user,
service.getBadges(user.id))
}9
RxJava Coroutines
suspend fun userDetail(user: User): UserStats {
return UserStats(user,
service.getBadges(user.id))
}9
RxJava Coroutines
fun userDetail(user: User): Single<UserStats> {
return Singles.zip(
service.getBadges(user.id).subscribeOn(io()),
service.getTags(user.id).subscribeOn(io())) {
badges, tags -> UserStats(user, badges, tags)
}7
}8
suspend fun userDetail(user: User): UserStats {
return UserStats(user,
service.getBadges(user.id))
}9
Coroutines
suspend fun userDetail(user: User): UserStats {
val badges = service.getBadges(user.id)
val tags = service.getTags(user.id)
return UserStats(user, badges, tags)
}9
Coroutines
suspend fun userDetail(user: User): UserStats {
val badges = async { service.getBadges(user.id) }
val tags = async { service.getTags(user.id) }
return UserStats(user, badges.await(), tags.await())7
}9
Coroutines
suspend fun userDetail(user: User): UserStats {
return coroutineScope {
val badges = async { service.getBadges(user.id) }
val tags = async { service.getTags(user.id) }
UserStats(user, badges.await(), tags.await())7
}8
}9
Coroutines
suspend fun userDetail(user: User): UserStats {
return coroutineScope {
val badges = async { service.getBadges(user.id) }
val tags = service.getTags(user.id)
UserStats(user, badges.await(), tags)7
}8
}9
Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
RxJava Coroutines
viewModelScope.launch {
try {
val users = service.getTopUsers()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
withTimeout(SECONDS.toMillis(10)) {
val users = service.getTopUsers().await()
updateUi(users)
}6
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retry(3)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
retry(3) {
withTimeout(SECONDS.toMillis(10)) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retry(3)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
retry(3) {
withTimeout(SECONDS.toMillis(10)) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
suspend fun <T> retry(attempts: Int,
f: suspend () -> T): T {
repeat(attempts - 1) {
try {
return f()
} catch (e: Exception) {
}
}
return f()
}
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retry(3)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
retry(3) {
withTimeout(SECONDS.toMillis(10)) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retryWhen(ExponentialBackoff(3))
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
viewModelScope.launch {
try {
exponentialBackoff(3) {
withTimeout(SECONDS.toMillis(10)) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
Wrapper of a synchronous method
fun myPref(): String =
prefs.getString("myPref", "")
fun myPref(): Single<String> =
Single.fromCallable {
prefs.getString("myPref", "")
}1
suspend fun myPref(): String =
withContext(IO) {
prefs.getString("myPref", "")
}2
RxJavaCoroutines
Wrapper of an asynchronous method
fun View.scale(v: Float): ViewPropertyAnimator {
return animate()
.scaleX(v)
.scaleY(v)
}4
Wrapper of an asynchronous method
fun View.scale(v: Float): ViewPropertyAnimator {
return animate()
.scaleX(v)
.scaleY(v)
}4
text.setOnClickListener {
text.scale(2f).withEndAction {
text.scale(1f)
}1
}2
Wrapper of an asynchronous method
fun View.scale(v: Float): ViewPropertyAnimator {
return animate()
.scaleX(v)
.scaleY(v)
}4
text.setOnClickListener {
text.scale(2f).withEndAction {
text.scale(1f).withEndAction {
text.scale(2f).withEndAction {
text.scale(1f)
}3
}4
}1
}2
Wrapper of an asynchronous method
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
val animator = animate()
animator.scaleX(value).scaleY(value).withEndAction {
emitter.onComplete()
}3
}4
text.setOnClickListener {
text.scale(2f).withEndAction {
text.scale(1f).withEndAction {
text.scale(2f).withEndAction {
text.scale(1f)
}3
}4
}1
}2
RxJava
Wrapper of an asynchronous method
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
val animator = animate()
animator.scaleX(value).scaleY(value).withEndAction {
emitter.onComplete()
}3
}4
text.setOnClickListener {
text.scale(2f)
.andThen(text.scale(1f))
.andThen(text.scale(2f))
.andThen(text.scale(1f))
.subscribe()
}2
RxJava
Wrapper of an asynchronous method
suspend fun View.scale(v: Float) =
suspendCoroutine<Unit> { continuation ->
animate()
.scaleX(v)
.scaleY(v)
.withEndAction { continuation.resume(Unit) }
}1
Coroutines
Wrapper of an asynchronous method
suspend fun View.scale(v: Float) =
suspendCoroutine<Unit> { continuation ->
animate()
.scaleX(v)
.scaleY(v)
.withEndAction { continuation.resume(Unit) }
}1
text.setOnClickListener {
launch {
text.scale(2f)
text.scale(1f)
text.scale(2f)
text.scale(1f)
}
}
Coroutines
Autocomplete
A
0
100
200
300
400
500
600
700
800
900
1000
L
Server
AL
AL -> Alabama, Alaska, California
A0
100
200
300
400
500
600
700
800
900
1000
L
Server
AL
AL -> Alabama, Alaska, California
A
ALA
ALA -> Alabama, Alaska
RxTextView.textChanges(auto_complete)
RxJava
RxTextView.textChanges(auto_complete)
.debounce(200, MILLISECONDS)
RxJava
RxTextView.textChanges(auto_complete)
.debounce(200, MILLISECONDS)
.switchMapSingle {
retrieveData(it.toString()).subscribeOn(io())
}
RxJava
RxTextView.textChanges(auto_complete)
.debounce(200, MILLISECONDS)
.switchMapSingle {
retrieveData(it.toString()).subscribeOn(io())
}
.subscribeOn(io())
.observeOn(mainThread())
RxJava
RxTextView.textChanges(auto_complete)
.debounce(200, MILLISECONDS)
.switchMapSingle {
retrieveData(it.toString()).subscribeOn(io())
}
.subscribeOn(io())
.observeOn(mainThread())
.subscribe {
adapter.clear()
adapter.addAll(it)
}
RxJava
val channel: SendChannel<String> = actor(capacity = CONFLATED) {
consumeEach { s ->
launch {
val data = retrieveData(s)
adapter.clear()
adapter.addAll(data)
}5
}5
}5
autoComplete.doOnTextChanged {
channel.offer(it)
}6
Coroutines
val channel: SendChannel<String> = actor(capacity = CONFLATED) {
consumeEach { s ->
launch {
val data = retrieveData(s)
adapter.clear()
adapter.addAll(data)
}5
}5
}5
autoComplete.doOnTextChanged {
channel.offer(it)
}6
Coroutines
val channel: SendChannel<String> = actor(capacity = CONFLATED) {
consumeEach { s ->
launch {
val data = retrieveData(s)
adapter.clear()
adapter.addAll(data)
}5
}5
}5
autoComplete.doOnTextChanged {
channel.offer(it)
}6
Coroutines
val channel: SendChannel<String> = actor(capacity = CONFLATED) {
consumeEach { s ->
launch {
val data = retrieveData(s)
adapter.clear()
adapter.addAll(data)
}5
}5
}5
autoComplete.doOnTextChanged {
channel.offer(it)
}6
Coroutines
val channel: SendChannel<String> = actor(capacity = CONFLATED) {
consumeEach { s ->
launch {
val data = retrieveData(s)
adapter.clear()
adapter.addAll(data)
}5
}5
}5
autoComplete.doOnTextChanged {
channel.offer(it)
}6
Coroutines
val channel: SendChannel<String> = actor(capacity = CONFLATED) {
var lastJob: Job? = null
consumeEach { s ->
lastJob?.cancel()
lastJob = launch {
delay(200)
val data = retrieveData(s)
adapter.clear()
adapter.addAll(data)
}5
}5
}5
autoComplete.doOnTextChanged {
channel.offer(it)
}6
Coroutines
Debugging
RxJava Coroutines
11051 io.reactivex
144 kotlin.coroutines
1984 kotlinx.coroutines
Method count - debug
427 io.reactivex
77 kotlin.coroutines
493 kotlinx.coroutines
Method count - release
RxJava and coroutines are both great,
which one should I use?
My algorithm:
If you are already using RxJava and it works for you ->
RxJava
If the architecture is based on reactive stream -> RxJava
If the project is multiplatform with Kotlin Native ->
Coroutines
If the codebase is Java/Kotlin -> RxJava
else -> Coroutines
RxJava and coroutines are both great,
which one should I use?
Links
Demo Project
github.com/fabioCollini/RxJavaVsCoroutines
Guide to kotlinx.coroutines by example
github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md
Kotlin coroutines, a deeper look
medium.com/@elizarov/kotlin-coroutines-a-deeper-look-180536305c3f
Async code using Kotlin Coroutines
proandroiddev.com/async-code-using-kotlin-coroutines-233d201099ff
ViewModelScope
android-review.googlesource.com/c/platform/frameworks/support/+/772083
Retrofit suspending methods support
github.com/square/retrofit/pull/2886
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
Android Developers Italia
androiddevs.it

Mais conteúdo relacionado

Mais procurados

The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]Nilhcem
 
Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaoneBrian Vermeer
 
"Quantum" performance effects
"Quantum" performance effects"Quantum" performance effects
"Quantum" performance effectsSergey Kuksenko
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Andres Almiray
 
Job Managment Portlet
Job Managment PortletJob Managment Portlet
Job Managment Portletriround
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Andres Almiray
 
"Quantum" Performance Effects
"Quantum" Performance Effects"Quantum" Performance Effects
"Quantum" Performance EffectsSergey Kuksenko
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyBrian Vermeer
 
Home Automation with Android Things and the Google Assistant
Home Automation with Android Things and the Google AssistantHome Automation with Android Things and the Google Assistant
Home Automation with Android Things and the Google AssistantNilhcem
 
Matching Game In Java
Matching Game In JavaMatching Game In Java
Matching Game In Javacmkandemir
 
Android Wear Essentials
Android Wear EssentialsAndroid Wear Essentials
Android Wear EssentialsNilhcem
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]Nilhcem
 

Mais procurados (14)

The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]The 2016 Android Developer Toolbox [NANTES]
The 2016 Android Developer Toolbox [NANTES]
 
Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaone
 
"Quantum" performance effects
"Quantum" performance effects"Quantum" performance effects
"Quantum" performance effects
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
 
Job Managment Portlet
Job Managment PortletJob Managment Portlet
Job Managment Portlet
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017
 
JDK8: Stream style
JDK8: Stream styleJDK8: Stream style
JDK8: Stream style
 
"Quantum" Performance Effects
"Quantum" Performance Effects"Quantum" Performance Effects
"Quantum" Performance Effects
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the Ugly
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
Home Automation with Android Things and the Google Assistant
Home Automation with Android Things and the Google AssistantHome Automation with Android Things and the Google Assistant
Home Automation with Android Things and the Google Assistant
 
Matching Game In Java
Matching Game In JavaMatching Game In Java
Matching Game In Java
 
Android Wear Essentials
Android Wear EssentialsAndroid Wear Essentials
Android Wear Essentials
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]
 

Semelhante a Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion Milan 2018

Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinFabio Collini
 
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingJavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingAnton Arhipov
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaFabio Collini
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaFabio Collini
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
Java 8 - Lambdas and much more
Java 8 - Lambdas and much moreJava 8 - Lambdas and much more
Java 8 - Lambdas and much moreAlin Pandichi
 
Functional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix APIFunctional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix APIC4Media
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 SlidesYarikS
 
Easy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTEasy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTDavid Chandler
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Artur Latoszewski
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Andres Almiray
 
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020AWSKRUG - AWS한국사용자모임
 
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaKotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaVíctor Leonel Orozco López
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonAEM HUB
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling RewriterJustin Edelson
 
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.UA Mobile
 

Semelhante a Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion Milan 2018 (20)

Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingJavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Java 8 - Lambdas and much more
Java 8 - Lambdas and much moreJava 8 - Lambdas and much more
Java 8 - Lambdas and much more
 
Functional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix APIFunctional Reactive Programming in the Netflix API
Functional Reactive Programming in the Netflix API
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
Easy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTEasy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWT
 
Exploring Kotlin
Exploring KotlinExploring Kotlin
Exploring Kotlin
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
Amplify를 통해 클라우드 기반 모바일 앱 개발하기 - 박태성(IDEASAM) :: AWS Community Day 2020
 
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaKotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin Edelson
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling Rewriter
 
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
Architecture Patterns in Practice with Kotlin. UA Mobile 2017.
 

Mais de Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyCodemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaCodemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserCodemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 - Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Codemotion
 

Mais de Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Último

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 

Último (20)

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 

Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion Milan 2018