Как вызвать метод после задержки в 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
                } );