Reputation: 493
I'm trying to replace my Handler method with RxJava.
My requirement:
I want to call the method getTransactionDetails() only after 5 seconds.
This my working code using Handler:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getTransactionDetails();
}
}, 5000);
Rx java code - it's not working:
Observable.empty().delay(5000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(o -> getTransactionDetails())
.subscribe();
Upvotes: 43
Views: 56098
Reputation: 93
Delay subscription already defined. Your example can be implemented in this way:
getTransactionDetails().delaySubscription(5000, TimeUnit.MILLISECONDS)
Upvotes: 7
Reputation: 141
If you want a disposable that can be used with the view then use a Completable Completable returns an Object which terminates as soon as one of the source Completables terminates (normally or with an error) and cancels all other Completables.
Eg :
Completable.timer(5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(() -> {
// code after delay here
});
If you want for a service to get complete i would recommend a Subscription
Eg :
observable.timer(5000, TimeUnit.MILLISECONDS)
.map(o -> {
// your code after delay here
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe( ()-<{
// enter the service here
} );
Upvotes: 2
Reputation: 5521
doOnNext()
is for side effects. It could be use for example for logging purpose, because logging doesn't alter the flow of data. But you want to pass down the result of getTransactionDetails()
, so you should use map instead.
Second, Observable.empty()
create an Observable
that just propagate the finish/dispose message, it trigger neither doOnNext()
neither map()
. You could fix this using Observable.just()
instead but a more idiomatic way would be to use Observable.timer()
:
Observable.timer(5000, TimeUnit.MILLISECONDS)
.map(o -> getTransactionDetails())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( ... );
A final note on Schedulers. Observable.timer()
and delay()
are executed on the computation scheduler by default so you don't need to call .subscribeOn(Schedulers.io())
to execute getTransactionDetails()
outside of main thread. Observable.timer()
and delay()
could take a Scheduler
as a parameter if you want to control this. So you need to call .observeOn(AndroidSchedulers.mainThread())
if you want to use getTransactionDetails()
result on UI thread. Every operator after observeOn()
is executed on the defined Scheduler
, so you have to put observeOn()
after computation.
Edit: This is of course if you care about the result of getTransactionDetails()
. If not, see Clyde answer.
Upvotes: 63
Reputation: 39
Try this
Observable.just(true).delay(5000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(o -> getTransactionDetails())
.subscribe();
Upvotes: 2
Reputation: 7549
This is how I would do it:
Completable.timer(5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(this::getTransactionDetails);
A Completable represents a deferred computation with no value but an indication for completion or exception. The static method call timer()
returns a Completable
that signals completion after the specified time period has elapsed, and the subscribe()
call will mean that the method getTransactionDetails()
will be called on the current object when the timer fires. By supplying a Scheduler
as the last argument to Completable.timer()
you control which thread is used to execute getTransactionDetails()
.
Upvotes: 91
Reputation: 255
Observable
.timer( 5000, TimeUnit.MILLISECONDS )
.subscribeOn(Schedulers.io())
.map(o -> getTransactionDetails() )
.subscribe();
you dont need observeOn because subscribe empty. use timer it will be more correct way
Upvotes: 13
Reputation: 895
It's not working, because delay()
needs something to be emitted, but empty()
actually emits nothing.
Instead, you should use Observable.timer()
.
Upvotes: 11