Using Transformation to debug Observables

One cool use case for transformations is to use them to print additional logging during the execution of the Observable. This can be really useful when what's happening inside the Observable flow is unclear. Sometimes the Observable can terminate abruptly with a regular onComplete() call, but you won't be able to find a reason why that is happening.

To help you debug cases like these, we can use a logging Transformer. In this section, we will create a tool for this--a logging Transformer.

Let's start by creating a class:

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;

public class LoggerTransformer<R>
implements ObservableTransformer<R, R> {

@Override
public ObservableSource<R> apply(Observable<R> upstream) {
}
}

In the apply() method, we can add a lot of tracking for different stages of an Observable's lifecycle to know what is going on:

@Override
public ObservableSource<R> apply(Observable<R> upstream) {
return upstream
.doOnNext(v -> this.log("doOnNext", v))
.doOnError(error -> this.log("doOnError", error))
.doOnComplete(() -> this.log("doOnComplete",
upstream.toString()))
.doOnTerminate(() -> this.log("doOnTerminate",
upstream.toString()))
.doOnDispose(() -> this.log("doOnDispose",
upstream.toString()))
.doOnSubscribe(v -> this.log("doOnSubscribe",
upstream.toString()));
}

This will make all steps that the Observable experiences plainly visible in the logs. As for logging methods, we will have these methods:

private void log(String stage, Object item) {
Log.d("APP-DEBUG:" + tag, stage + ":" + Thread.currentThread().getName() +
":" + item);
}

private void log(String stage, Throwable throwable) {
Log.e("APP-DEBUG:" + tag, stage + ":" +
Thread.currentThread().getName() + ":
error"
, throwable);
}

As you can see, we have a tag that we will use to differentiate between different instances of the LoggerTransformer. To pass the relevant tag, we will create a Factory Method along with a constructor:

private final String tag;

public LoggerTransformer(String tag) {
this.tag = tag;
}

public static <R> LoggerTransformer<R> debugLog(String tag) {
return new LoggerTransformer<>(tag);
}

Finally, the Transformer is used as shown here:

Observable.interval(1, TimeUnit.SECONDS)
.compose(debugLog("afterInterval"))
.flatMap((v) -> Observable.just("items"))
.observeOn(AndroidSchedulers.mainThread())
.compose(debugLog("afterFlatMap"))
.subscribe();

By inserting calls, such as the following, in multiple places, you will be able to see where the Observable starts its termination, which items reach which parts of the flow, and when the unsubscribe (dispose) actually happens:

.compose(debugLog("afterInterval"))

This can be a very powerful tool in your toolbox.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.176.166