Search code examples
androidrx-java2rx-android

Why in RxAndroid using compose running in main thread while using map running in io thread?


I have this piece of code you can see when I am using map for the transformation the currentThread is background thread while I am using compose() it is in main thread . Why it works this way and I could not find document about this.

public Single<Content> fetchContent() {
    return mEndpoint.content(id);
}


public Single<Content> fetchContent() {
    return mEndpoint.fetchContent()
            .map(content -> {
                Log.i("thread-name", "map" + Thread.currentThread());
                return content;
            })
            .compose(content -> {
                Log.i("thread-name", "compose" + Thread.currentThread());
                return content;
            });
}

//thread-name: compose. Thread[main,5,main]
//thread-name: map. Thread[OkHttp ...,10,main]



Solution

  • As explained in the comments compose will execute the lambda right away and therefore the print statement is ran on the main thread.

    However, the argument to compose is actually the observable that will emit the content and not the content itself. So you actually want to operate on this just like a normal observable. Here's, for example, a map function that will not run on the main thread:

    mEndpoint.fetchContent()
            .map(content -> {
                Log.i("thread-name", "map" + Thread.currentThread());
                return content;
            })
            .compose(content -> content.map(it -> {
               Log.i("thread-name", "map" + Thread.currentThread());
    
               return it;
            }))
    

    Note that I've kept the variable name content the same so you can see the differences easily, but it should actually be more like this:

    .compose(obs -> obs.map(content -> {
               Log.i("thread-name", "map" + Thread.currentThread());
    
               return content;
            }))
    

    One last thing, I usually use compose when I have several operations that I can apply to an observable and reuse them in other chains. For simple mappings I usually stick to map and friends.