RxJava: Take care of code running on main thread

Recently I have faced one problem on an android project related to RxJava, but first I want to explain two important things:

ANR

Acronym for “Application not responding”, if you are an android developer and you don’t know this concept, you should.

ANR is one of the Android Vitals, these are metrics related to the perfomance of your application, tracked by Google. This Android Vitals really affects the ranking of your app and you should take care of it if you want to deliver an app with good quality.

This message will be shown to the user every time your UI thread is blocked for too long (approximately 5 seconds).

NetworkOnMainThreadException

This exception will be thrown every time you make a network operation on the main or UI thread.

How can we easily fall into this errors with RxJava

So imagine this two classes:

class UserRepository (
val service: UserService
) {
fun getUser(): Single<User> {
return service.getUser()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
class ProfileViewModel (
val userRepository: UserRepository,
val movieRepository: MovieRepository,
val databaseController: DbController
) {
fun getMovies(): {
service.getUser()
.flatMap { user -> movieRepository.getMoviesFor(user) }
.subscribe({//do stuff})
} fun saveUserToDb() : {
service.getUser()
.doOnNext { user -> databaseController.saveUser(user) }
.subscribe({//do stuff})
}

}

Assuming that movieRepository.getMoviesFor(user) makes an HTTP request, what will happen when you call the method getMovies() of the ProfileVIewModel?

It will throw a NetworkOnMainThreadException, because inside your repository you set the observer scheduler on main thread.

In saveUserToDb() method you could get an ANR, because you are making I/O operations on the main thread, and remember: I/O operations, or long running operations can produce an ANR.

Conclusion

Maybe you are thinking this is an obvious mistake, but on large projects when you usually have to make a change on the ViewModel, surely you will don’t even look the code at the repository layer

Senior Android Engineer at Cognizant Softvision

Senior Android Engineer at Cognizant Softvision