When we work with Android, we should remember that we have a main thread that is responsible for a user interface. First, it is not a good idea to invoke long-term operations in the main thread, because in that case, a user interface freezes. Secondly, when we invoke a synchronous method, this blocks a thread. Our user interface is unresponsive until a function that is invoked from the main thread returns the result. That is why we should invoke a long-term operation asynchronously, and reactive programming can help us to do just that.
The Mono and Flux classes contain the publishOn and subscribeOn methods that can switch threads when operators are invoked. The subscribeOn method is used to specify a scheduler that produces emitted values, and the publishOn is used to specify a thread scheduler for the downstream of an observable.
Scheduler is an abstraction over thread pool. The following example code creates our own scheduler that uses the main thread:
val UIScheduler = Schedulers.fromExecutor { runnable -> Handler(Looper.getMainLooper()).post(runnable)
}
Now, we can rewrite an example from the Mono publisher section, in the following way:
Mono.fromDirect<Comic> { subscriber -> subscriber.onNext(loadComic()) }
.map { comic -> comic.img }
.flatMap { path -> Mono.fromDirect<Bitmap> { subscriber -> subscriber.onNext(loadBitmap(path)) } }
.subscribeOn(Schedulers.single())
.publishOn(UIScheduler)
.subscribe { bitmap -> findViewById<ImageView>(R.id.imageView).setImageBitmap(bitmap) }
The single function of the Schedulers class returns an instance of the Scheduler type that creates and uses a single thread under the hood. The subscribeOn method specifies that all operators from the upstream have to use a scheduler that is returned by the single() function.
We pass our own scheduler that uses the main thread under the hood. For this reason, the lambda that is passed to the subscribe method is performed on the main thread.
The following diagram shows how this works:
The diagram shows that the main thread is not blocked, and runs with a background, in parallel.