• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Codemotion Magazine

We code the future. Together

  • Discover
    • Events
    • Community
    • Partners
    • Become a partner
    • Hackathons
  • Magazine
    • Backend
    • Frontend
    • AI/ML
    • DevOps
    • Dev Life
    • Soft Skills
    • Infographics
  • Talent
    • Discover Talent
    • Jobs
    • Manifesto
  • Companies
  • For Business
    • EN
    • IT
    • ES
  • Sign in

Vito GentileAugust 13, 2020

Async code on Kotlin: coroutines VS RxJava

Mobile Developer
mobile development developer
facebooktwitterlinkedinreddit
Table Of Contents
  1. What are coroutines?
  2. What is RxJava?
  3. A sample service in Kotlin
  4. Using service methods
  5. Coroutines or RxJava?
  6. Conclusions

A lot of Android programmers are now exploring Kotlin, a programming language based on Java and the JVM that is used to develop Android applications. As is often the case with Java-based Android apps, one of the main problems when approaching Android development in Kotlin is the management of asynchronous code. In Java, this has been solved by the AsyncTask class, or the runOnUiThread method. In Kotlin, something different is required.

At Codemotion Milan 2018, Fabio Collini, Google Developer Expert and Senior Android Developer, delivered a speech on how to implement asynchronous code in Kotlin. Specifically, he described two different approaches: the first using coroutines, the second based on a library named ReactiveX Java (or RxJava in short). Both of these approaches allow users to implement and support asynchronous operations, and can be also used both together and interchangeably.
This post provides a quick overview on how these approaches differ from each other.

Recommended article
Android App Development Languages: all you need to know. Introduction to Kotlin.
December 11, 2023

Using MQTT with Android: A Practical Guide

Gilad David Maayan

Mobile Developer

Before starting, let’s try to understand more clearly the main differences between RxJava and coroutines, and how they can help Kotlin programmers.

What are coroutines?

The concept of coroutine is not strictly related to Kotlin. Coroutines are in fact components that generalize subroutines for non-preemptive multitasking, which allows tasks to suspend and resume their own execution. These components are therefore particularly useful for multi-thread programming, and are also found in other languages such as Python or C#.

In Kotlin, coroutines are implemented within the kotlinx.coroutines library, originally developed by JetBrains. The Kotlin official documentation provides an extensive ‘how to’ guide that is available at this link.

What is RxJava?

RxJava, shorthand for ‘ReactiveX for Java‘, was created by Ben Christensen and David Karnok, with the first version released in November 2014. RxJava has found several applications in the Android world, thanks to its unique features. Indeed, this library allows easy termination of subscription when an activity is ending, thus avoiding memory leaks and the waste of resources derived from working on UI elements that are no longer visible.

Moreover, RxJava is considered one of the most fruitful methods for enabling Reactive Programming in Android development. As we’ll see below, the result is simplified implementation of concurrency and the asynchronous tasks inherent in mobile programming.

Although it is also available for Java,this article will focus on how to use RxJava to implement mobile apps in Kotlin.

A sample service in Kotlin

Fabio Collini started the discussion about using RxJava or coroutines by showing a sample interface for a service aimed at obtaining information from StackOverflow. Since such a service is made up of asynchronous methods, it is perfect for our purposes.

The first question is therefore how to define methods that are asynchronous? With RxJava, we need to use a Single class as type for the return value:

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>>
}

This allows use of the subscribe method in order to wait for the response.
With coroutines, there are two possibilities: the first is similar to the above, but uses the Deferred class:

interface StackOverflowService {
	@GET("/users")
	fun getTopUsers(): Deferred<List<User>>
    
	@GET("/users/{userId}/badges")
	fun getBadges(
    		@Path("userId") userId: Int
	): Deferred<List<Badge>>
    
	@GET("/users/{userId}/top-tags")
	fun getTags(
   		@Path("userId") userId: Int
	): Deferred<List<Tag>>
}

However, a recent upgrade of Kotlin allows for declaration of suspending functions, which in practice makes the code appears synchronous, even it is actually the opposite:

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>
}

In what follows, we will consider the latter approach, which makes the code cleaner.

Using service methods

Now, if we want to use the aforementioned service, RxJava and coroutines require different approaches. As mentioned above, RxJava requires using the subscribe method:

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) }
				)
	}
    
	private fun updateUi(s: Any) {
		//...
	}
    
	override fun onCleared() {
		disposable.clear()
	}
}

The subscribe method accepts two parameters: the first is the one we want to execute, while the second (e -> updateUi(e)) is used in case of errors.

While RxJava is synchronous by default (one consequence of this is that we resorted to subscribe), using coroutines and suspending functions allows us to write code that is automatically interpreted as asynchronous, even if it appears synchronous. To understand this difference, compare the following snippet with the previous one: they are equivalent in functionality.

class MyViewModel(
	private val service: StackOverflowService
) : ViewModel() {

	fun load() {
		viewModelScope.launch {
			try {
				val users = service.getTopUsers()
				updateUi(users)
			} catch (e: Exception) {
				updateUi(e)
			}
		}
	}
    
	private fun updateUi(s: Any) {
		//...
	}
}

Here, viewModelScope simplifies the code, even if it is not available yet using Kotlin. However, an implementation is provided in this link.

In general, even more complicated things are made possible by using coroutines or RxJava. Additional code examples by Fabio Collini are available on GitHub.

Coroutines or RxJava?

Having read this quick overview of coroutines and RxJava, one might ask which solution is the best. In terms of number of methods, RxJava is bigger than a solution based on coroutines only. However, this difference can be eliminated by using Proguard and its code optimization. The following graphs taken from Fabio Collini’s slides show this.

Conclusions

So, which approach should we use for production code?
In order to answer such a question, Fabio Collini proposed the following ‘algorithm’:

  • if you are already using RxJava and it works for you, then use RxJava
  • if the architecture is based on a reactive stream, then use RxJava
  • if the project is multiplatform with Kotlin Native, then use coroutines
  • if the codebase is Java/Kotlin, then use RxJava
  • otherwise, use coroutines

An additional note: consider that coroutines are generally easier to understand, while the learning curve for RxJava is steep. This makes coroutines generally preferable, except in the aforementioned cases.

Related Posts

tools for android developers. Artificial Intelligence tools and frameworks.

AI-Powered Tools for Android Developers: Supercharging Your Development Process

Codemotion
October 13, 2023
cross-platform development, frameworks

Ionic Framework: Why It’s Still Relevant

Lucilla Tomassi
September 19, 2023
frontend, sicurezza, mobile, kotlin,

Why Kotlin Is a Strong Choice for Mobile Development

Codemotion
September 1, 2023
kotlin

Discover Arrow: Functional Programming in Kotlin, and More!

Codemotion
May 10, 2023
Share on:facebooktwitterlinkedinreddit

Tagged as:Codemotion Milan Kotlin Mobile

Vito Gentile
I’m a data scientist, tech writer, software developer with experience in mobile, web (full-stack) and Python programming, and former researcher with interests in human-computer interaction. I thus have a multi-faceted experience in the area of software development, and that’s why I love my job(s)!
What a Security Engineer & Software Engineer Learned by Swapping Roles
Previous Post
Genetic Algorithms: A Developer’s Perspective
Next Post

Footer

Discover

  • Events
  • Community
  • Partners
  • Become a partner
  • Hackathons

Magazine

  • Tech articles

Talent

  • Discover talent
  • Jobs

Companies

  • Discover companies

For Business

  • Codemotion for companies

About

  • About us
  • Become a contributor
  • Work with us
  • Contact us

Follow Us

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions