Как вызвать метод после задержки в android с помощью rxjava?
Я пытаюсь заменить метод Handler на RxJava.
Мое требование:
Я хочу вызвать метод getTransactionDetails() только после 5 секунд.
Это мой рабочий код с использованием Handler:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getTransactionDetails();
}
}, 5000);
Rx Java-код - это не работает:
Observable.empty().delay(5000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(o -> getTransactionDetails())
.subscribe();
Ответы
Ответ 1
doOnNext()
для побочных эффектов. Его можно использовать, например, для целей ведения журнала, поскольку ведение журнала не изменяет поток данных. Но вы хотите передать результат getTransactionDetails()
, поэтому вместо этого вы должны использовать карту.
Во-вторых, Observable.empty()
создает Observable
которые просто распространяют сообщение finish/doOnNext()
, оно не вызывает ни doOnNext()
ни map()
. Вы можете исправить это, используя Observable.just()
но более идиоматичным способом было бы использовать Observable.timer()
:
Observable.timer(5000, TimeUnit.MILLISECONDS)
.map(o -> getTransactionDetails())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( ... );
Окончательная заметка о планировщиках. Observable.timer()
и delay()
выполняются по расписанию вычислений по умолчанию, поэтому вам не нужно вызывать .subscribeOn(Schedulers.io())
для выполнения getTransactionDetails()
вне основного потока. Observable.timer()
и delay()
могут принимать Scheduler
в качестве параметра, если вы хотите его контролировать. Поэтому вам нужно вызвать .observeOn(AndroidSchedulers.mainThread())
если вы хотите использовать результат getTransactionDetails()
в потоке пользовательского интерфейса. Каждый оператор после функции observeOn()
выполняется в определенном Scheduler
, поэтому после вычисления необходимо выставить observeOn()
после вычисления.
Изменить: это, конечно, если вы заботитесь о результате getTransactionDetails()
. Если нет, см. Ответ Клайда.
Ответ 2
Вот как я это сделаю:
Completable.timer(5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(this::getTransactionDetails);
A Completable представляет собой отложенное вычисление без значения, но указывает на завершение или исключение. timer()
статического метода timer()
возвращает завершающий Completable
который завершает завершение по прошествии указанного периода времени, а вызов subscribe()
будет означать, что метод getTransactionDetails()
будет вызываться в текущем объекте при срабатывании таймера. Предоставляя Scheduler
в качестве последнего аргумента для Completable.timer()
вы контролируете, какой поток используется для выполнения getTransactionDetails()
.
Ответ 3
Observable
.timer( 5000, TimeUnit.MILLISECONDS )
.subscribeOn(Schedulers.io())
.map(o -> getTransactionDetails() )
.subscribe();
вы не нуждаетесь в наблюдении, потому что подписываетесь пустым. используйте таймер, это будет более правильным способом
Ответ 4
Он не работает, потому что delay()
нуждается в том, чтобы что-то выпустить, но empty()
фактически ничего не испускает.
Вместо этого вы должны использовать Observable.timer()
.
Ответ 5
Попробуй это
Observable.just(true).delay(5000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(o -> getTransactionDetails())
.subscribe();
Ответ 6
Задержка подписки уже определена. Ваш пример может быть реализован следующим образом:
getTransactionDetails().delaySubscription(5000, TimeUnit.MILLISECONDS)
Ответ 7
Если вы хотите использовать одноразовое представление, которое можно использовать с представлением, то используйте Completable Completable возвращает объект, который завершается, как только завершается один из исходных Completables (обычно или с ошибкой), и отменяет все другие Completables.
Например:
Completable.timer(5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(() -> {
// code after delay here
});
Если вы хотите получить услугу, я рекомендую подписку
Например:
observable.timer(5000, TimeUnit.MILLISECONDS)
.map(o -> {
// your code after delay here
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe( ()-<{
// enter the service here
} );