doOnSubscribe gets called on main thread

By default doOnSubscribe executes on the current thread. To change the thread in which doOnSubscribe is executed put subscribeOn below it.

 Observable.just(1)
            .doOnSubscribe(s -> System.out.println("doOnSubscribe thread " + Thread.currentThread().getName())) //IO thread
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.computation())
            .subscribe(s -> {
                System.out.println("subscribing thread " + Thread.currentThread().getName());//Computation thread
            });
Thread.sleep(100);

subscribeOn and observeOn have no effect on doOnSubscribe because the connection between operators are established on the caller thread in order to support immediate cancellation. You have to defer the subscription to a doOnSubscribe in some way, e.g.:

Observable.defer(() ->
    Observable.just(1)
    .doOnSubscribe(s -> Log.d("Testing", "Testing"))
)
.subscribeOn(Schedulers.io())
.subscribe();

or

Observable.just(1)
.subscribeOn(Schedulers.io())
.flatMap(v ->
    Observable.just(1)
    .doOnSubscribe(s -> Log.d("Testing", "Testing"))
)
.subscribe()