RxKotlin: Prefetch with Single in Android

Andy Wang
Andy Wang
Aug 29, 2017 · 2 min read

This story is inspired by

https://blog.mindorks.com/rxjava-clean-way-of-prefetching-data-and-use-later-54800f2652d4

Now I’d like to share my recipe of doing prefetch with Single observable. This story assumes you understand the MVP architecture and basics of RxKotlin.


RxJava comes with this handy API called Single.cache(). What it does is to return a Single observable instance that will cache the result or exception emitted by this Single. Let’s see an example. Assume you have an Action B depend on an async Task A.

class SomePresenter() {
lateinit var Single<ResultOfTaskA> taskA

fun startPrefetch() {
taskA = Single.defer(taskA).cache()
}
fun actionB() {
val resultA = taskA.blockGet()
// do anything depend on result A ...
}
}

This is NOT quite what we wanted because Task A is not actually started until the blockGet() is called. WHAT !!!

Because cache() returns a cold observable which does not start execution until subscribe(blockGet() in this example) is called. To convert from a cold observable to a hot observable, you just simply call the subscribe() on the observable.

class SomePresenter() {
lateinit var Single<ResultOfTaskA> taskA
// if you want the next prefetch task cancels the previous one
// i.e. autocomplete
var disposable: Disposable?
fun startPrefetch() {
disposable?.dispose()
taskA = Single.defer(taskA).cache()
disposable = taskA.subscribe()
}
fun actionB() {
taskA.subscribe({ resultA -> // do action B}, { throwable -> // handle error})
}
}

There are some exceptions that you can create() a hot Observable directly. Code will be executed on the creation of the observable.

i.e. Single<Bitmap>.create { emitter -> emitter.onSuccess(bitmap.compress(...)) }.subscribe({ bitmap -> // handle compressed bitmap })

Be careful not to run this in the UI thread. Use defer() instead.

i.e. Single<Bitmap>.defer { Single.just(bitmap.compress(...) }.subscribeOn(Scheduler.io()).observeOn(AndroidScheduler.mainThread()).subscribe{ bitmap -> // handle compressed bitmap }


Leave a comment if you think there are other ways of doing it. Claps if you like it.

)

Andy Wang

Written by

Andy Wang

Full-stack Android Developer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade