io.reactivex.functions.BiFunction Java Examples

The following examples show how to use io.reactivex.functions.BiFunction. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ChapterFour.java    From RxJava2Demo with Apache License 2.0 6 votes vote down vote up
public static void practice1(){
    final Api api = RetrofitProvider.get().create(Api.class);
    Observable<UserBaseInfoResponse> observable1 =
            api.getUserBaseInfo(new UserBaseInfoRequest()).subscribeOn(Schedulers.io());

    Observable<UserExtraInfoResponse> observable2 =
            api.getUserExtraInfo(new UserExtraInfoRequest()).subscribeOn(Schedulers.io());

    Observable.zip(observable1, observable2,
            new BiFunction<UserBaseInfoResponse, UserExtraInfoResponse, UserInfo>() {
                @Override
                public UserInfo apply(UserBaseInfoResponse baseInfo,
                                      UserExtraInfoResponse extraInfo) throws Exception {
                    return new UserInfo(baseInfo, extraInfo);
                }
            }).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<UserInfo>() {
                @Override
                public void accept(UserInfo userInfo) throws Exception {
                    //do something;
                }
            });
}
 
Example #2
Source File: Step.java    From RIBs with Apache License 2.0 6 votes vote down vote up
/**
 * Chains another step to be performed after this step completes. If the previous step results in
 * an error and does not emit a new actionable item, future chained onStep calls will not be
 * called.
 *
 * @param func to return the next step when this current step completes. This function will
 *     receive the result of the previous step and the next actionable item to take an action on.
 * @param <TNewValueType> the value type returned by the next step.
 * @param <TNewActionableItem> the actionable item type returned by the next step.
 * @return a {@link Step} to chain more calls to.
 */
public <TNewValueType, TNewActionableItem extends ActionableItem>
    Step<TNewValueType, TNewActionableItem> onStep(
        final BiFunction<T, A, Step<TNewValueType, TNewActionableItem>> func) {
  return new Step<>(
      asObservable()
          .flatMap(
              new Function<
                  Optional<Data<T, A>>,
                  Observable<Optional<Data<TNewValueType, TNewActionableItem>>>>() {
                @Override
                public Observable<Optional<Data<TNewValueType, TNewActionableItem>>> apply(
                    Optional<Data<T, A>> dataOptional) throws Exception {
                  if (dataOptional.isPresent()) {
                    Data<T, A> data = dataOptional.get();
                    return func.apply(data.value, data.actionableItem).asObservable();
                  } else {
                    return Observable.just(
                        Optional.<Data<TNewValueType, TNewActionableItem>>absent());
                  }
                }
              })
          .singleOrError());
}
 
Example #3
Source File: LifeCycleHelper.java    From Tangram-Android with MIT License 6 votes vote down vote up
public static <T, E> LifecycleTransformer<T> bindToLifeCycle(Observable<E> lifecycle,
    final Function<E, E> correspondingEvents) {
    Observable<E> lifecycleCopy = lifecycle.share();
    return new LifecycleTransformer<>(Observable.combineLatest(lifecycle.take(1).map(correspondingEvents),
        lifecycleCopy.skip(1),
        new BiFunction<E, E, Boolean>() {

            @Override
            public Boolean apply(E e, E e2) throws Exception {
                return e.equals(e2);
            }
        }).filter(new Predicate<Boolean>() {
        @Override
        public boolean test(Boolean cmpResult) throws Exception {
            return cmpResult;
        }
    }));
}
 
Example #4
Source File: Transformers.java    From rxjava2-extras with Apache License 2.0 6 votes vote down vote up
public static <T, R extends Number> FlowableTransformer<T, Pair<T, Statistics>> collectStats(
        final Function<? super T, ? extends R> function) {
    return new FlowableTransformer<T, Pair<T, Statistics>>() {

        @Override
        public Flowable<Pair<T, Statistics>> apply(Flowable<T> source) {
            return source.scan(Pair.create((T) null, Statistics.create()),
                    new BiFunction<Pair<T, Statistics>, T, Pair<T, Statistics>>() {
                        @Override
                        public Pair<T, Statistics> apply(Pair<T, Statistics> pair, T t) throws Exception {
                            return Pair.create(t, pair.b().add(function.apply(t)));
                        }
                    }).skip(1);
        }
    };
}
 
Example #5
Source File: RxSQLiteTest.java    From SQLite with Apache License 2.0 6 votes vote down vote up
@Test
public void testElementsList() throws Exception {
    List<TestObject> elements = new ArrayList<>();
    elements.add(new TestObject(1, 9.5, "a"));
    elements.add(new TestObject(2, 6.7, "ab"));
    elements.add(new TestObject(3, 8.2, "abc"));
    elements.add(new TestObject(4, 3.4, "abcd"));
    elements.add(new TestObject(5, 6.5, "abcde"));
    SQLite.get().insert(TestTable.TABLE, elements);

    Observable.zip(RxSQLite.get().query(TestTable.TABLE),
            Observable.just(elements), new BiFunction<List<TestObject>, List<TestObject>, Object>() {
                @Override
                public Object apply(List<TestObject> testElements, List<TestObject> savedElements) throws Exception {
                    assertEquals(testElements.size(), savedElements.size());
                    for (int i = 0; i < testElements.size(); i++) {
                        assertEquals(testElements.size(), savedElements.size());
                    }
                    return null;
                }
            })
            .test();
}
 
Example #6
Source File: RetryWhenNetworkException.java    From GankGirl with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
public Observable<?> apply(Observable<? extends Throwable> flowable) throws Exception {
    return flowable.zipWith(Observable.range(1, count + 1), new BiFunction<Throwable, Integer, Wrapper>() {
        @Override
        public Wrapper apply(Throwable throwable, Integer integer) throws Exception {
            return new Wrapper(throwable, integer);
        }
    }).flatMap(wrapper -> {
        if ((wrapper.throwable instanceof ConnectException
                || wrapper.throwable instanceof SocketTimeoutException
                || wrapper.throwable instanceof TimeoutException)
                && wrapper.index < count + 1) {
            return Observable.timer(delay + (wrapper.index - 1) * delay, TimeUnit.MILLISECONDS);
        }
        return Observable.error(wrapper.throwable);
    } );
}
 
Example #7
Source File: MainActivity.java    From RxRetroJsoup with Apache License 2.0 6 votes vote down vote up
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView = (RecyclerView) findViewById(R.id.recyclerview);

    recyclerView.setLayoutManager(new LinearLayoutManager(getBaseContext()));
    adapter = new Adapter();
    recyclerView.setAdapter(adapter);

    loadWithRetroJsoup();

    Observable.zip(
            Observable.just(""),
            Observable.just("&"),
            new BiFunction<String, String, String>(){

                @Override
                public String apply(@NonNull String s, @NonNull String s2) throws Exception {
                    return null;
                }
            }
    );
}
 
Example #8
Source File: TransactionServiceImpl.java    From symbol-sdk-java with Apache License 2.0 6 votes vote down vote up
private Observable<TransactionFactory<? extends Transaction>> resolveTransactionFactory(
    AccountAddressRestrictionTransaction transaction,
    ReceiptSource expectedReceiptSource) {
    Observable<Statement> statementObservable = getStatement(transaction);
    Observable<List<UnresolvedAddress>> unresolvedAdditions = getResolvedAddresses(transaction,
        transaction.getRestrictionAdditions(), statementObservable, expectedReceiptSource);

    Observable<List<UnresolvedAddress>> unresolvedDeletions = getResolvedAddresses(transaction,
        transaction.getRestrictionDeletions(), statementObservable, expectedReceiptSource);

    BiFunction<List<UnresolvedAddress>, List<UnresolvedAddress>, AccountAddressRestrictionTransactionFactory> mapper =
        (additions, deletions) -> AccountAddressRestrictionTransactionFactory
            .create(transaction.getNetworkType(), transaction.getRestrictionFlags(), additions,
                deletions);
    return Observable.combineLatest(unresolvedAdditions, unresolvedDeletions, mapper);
}
 
Example #9
Source File: TransactionServiceImpl.java    From symbol-sdk-java with Apache License 2.0 6 votes vote down vote up
private Observable<TransactionFactory<? extends Transaction>> resolveTransactionFactory(
    AccountMosaicRestrictionTransaction transaction,
    ReceiptSource expectedReceiptSource) {
    Observable<Statement> statementObservable = getStatement(transaction);
    Observable<List<UnresolvedMosaicId>> unresolvedAdditions = getResolvedMosaicIds(transaction,
        transaction.getRestrictionAdditions(), statementObservable, expectedReceiptSource);

    Observable<List<UnresolvedMosaicId>> unresolvedDeletions = getResolvedMosaicIds(transaction,
        transaction.getRestrictionDeletions(), statementObservable, expectedReceiptSource);

    BiFunction<List<UnresolvedMosaicId>, List<UnresolvedMosaicId>, TransactionFactory<AccountMosaicRestrictionTransaction>> mapper =
        (additions, deletions) -> AccountMosaicRestrictionTransactionFactory
            .create(transaction.getNetworkType(), transaction.getRestrictionFlags(), additions,
                deletions);
    return Observable.combineLatest(unresolvedAdditions, unresolvedDeletions, mapper);
}
 
Example #10
Source File: TransactionServiceImpl.java    From symbol-sdk-java with Apache License 2.0 6 votes vote down vote up
private Observable<TransactionFactory<? extends Transaction>> resolveTransactionFactory(
    MosaicAddressRestrictionTransaction transaction,
    ReceiptSource expectedReceiptSource) {
    Observable<Statement> statementObservable = getStatement(transaction);
    Observable<MosaicId> resolvedMosaicId = getResolvedMosaicId(transaction,
        transaction.getMosaicId(),
        statementObservable, expectedReceiptSource);

    Observable<Address> resolvedTargetAddress = Observable
        .just(transaction.getTargetAddress())
        .flatMap(m -> getResolvedAddress(transaction, m, statementObservable,
            expectedReceiptSource));

    BiFunction<? super MosaicId, ? super Address, MosaicAddressRestrictionTransactionFactory> mapper = (mosaicId, targetAddress) ->
        MosaicAddressRestrictionTransactionFactory
            .create(transaction.getNetworkType(), mosaicId,
                transaction.getRestrictionKey(), targetAddress,
                transaction.getNewRestrictionValue())
            .previousRestrictionValue(transaction.getPreviousRestrictionValue());
    return Observable.combineLatest(resolvedMosaicId, resolvedTargetAddress, mapper);
}
 
Example #11
Source File: TransactionServiceImpl.java    From symbol-sdk-java with Apache License 2.0 6 votes vote down vote up
private Observable<TransactionFactory<? extends Transaction>> resolveTransactionFactory(
    TransferTransaction transaction, ReceiptSource expectedReceiptSource) {
    Observable<Statement> statementObservable = getStatement(transaction);
    Observable<List<Mosaic>> resolvedMosaics = Observable
        .fromIterable(transaction.getMosaics()).flatMap(
            m -> getResolvedMosaic(transaction, m, statementObservable, expectedReceiptSource))
        .toList().toObservable();

    Observable<Address> resolvedRecipient = getResolvedAddress(transaction,
        transaction.getRecipient(),
        statementObservable, expectedReceiptSource);

    BiFunction<Address, List<Mosaic>, TransferTransactionFactory> mergeFunction = (address, mosaics) ->
        TransferTransactionFactory
            .create(transaction.getNetworkType(), address, mosaics, transaction.getMessage());
    return Observable.combineLatest(resolvedRecipient, resolvedMosaics, mergeFunction);
}
 
Example #12
Source File: BlockServiceImpl.java    From symbol-sdk-java with Apache License 2.0 6 votes vote down vote up
private Observable<Boolean> getBooleanObservable(Observable<String> rootObservable, String leaf,
    Observable<MerkleProofInfo> merkleTransactionObservable) {

    BiFunction<String, MerkleProofInfo, Boolean> zipper = (root, merkleProofInfo) -> {
        List<MerklePathItem> merklePath = merkleProofInfo.getMerklePath();
        if (merklePath.isEmpty()) {
            // Single item tree, so leaf = HRoot0
            return leaf.equalsIgnoreCase(root);
        }

        // 1 is left
        java.util.function.BiFunction<String, MerklePathItem, String> accumulator = (proofHash, pathItem) -> ConvertUtils
            .toHex(Hashes
                .sha3_256(ConvertUtils
                    .fromHexToBytes(
                        pathItem.getPosition() == Position.LEFT ? pathItem.getHash() + proofHash
                            : proofHash + pathItem.getHash())));

        String hroot0 = merklePath.stream().reduce(leaf, accumulator, (s1, s2) -> s1);
        return root.equalsIgnoreCase(hroot0);
    };
    return Observable.zip(rootObservable, merkleTransactionObservable, zipper).onErrorReturn((e) -> {
        e.printStackTrace();
        return false;
    });
}
 
Example #13
Source File: Network3Fragment.java    From AndroidQuick with MIT License 6 votes vote down vote up
private void clickAsyncZip() {
    TestApis testApis = RetrofitManager.INSTANCE.getRetrofit(Constants.GANK_API_URL).create(TestApis.class);
    Observable<TSSCRes<TSSCResult>> o1 = testApis.getTangShiSongCi();
    Observable<XHYRes<XHYResult>> o2 = testApis.getXHY();
    Observable.zip(o1, o2, new BiFunction<TSSCRes<TSSCResult>, XHYRes<XHYResult>, Integer>() {
        @Override
        public Integer apply(TSSCRes<TSSCResult> tsscRes, XHYRes<XHYResult> xhyRes) throws Exception {
            return tsscRes.getResult().size() + xhyRes.getResult().size();
        }
    }).subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .subscribe(new BaseObserver<Integer>() {

                           @Override
                           public void onError(ApiException exception) {
                               LogUtil.e(TAG, "error:" + exception.getMessage());
                           }

                           @Override
                           public void onSuccess(Integer count) {
                               LogUtil.e(TAG, "count = " + count);
                           }
                       }
            );
}
 
Example #14
Source File: SynchronousColumnQueryTest.java    From sqlitemagic with Apache License 2.0 6 votes vote down vote up
@Test
public void avgFunction() {
  final double count = 8;
  final Integer sum = Observable.fromIterable(insertSimpleAllValues((int) count))
      .map(new Function<SimpleAllValuesMutable, Integer>() {
        @Override
        public Integer apply(SimpleAllValuesMutable v) {
          return (int) v.primitiveShort;
        }
      })
      .reduce(new BiFunction<Integer, Integer, Integer>() {
        @Override
        public Integer apply(Integer v1, Integer v2) {
          return v1 + v2;
        }
      })
      .blockingGet();

  final Double value = Select
      .column(avg(SIMPLE_ALL_VALUES_MUTABLE.PRIMITIVE_SHORT))
      .from(SIMPLE_ALL_VALUES_MUTABLE)
      .takeFirst()
      .execute();
  assertThat(value).isEqualTo(sum.doubleValue() / count);
}
 
Example #15
Source File: RxJavaOperatorActivity.java    From My-MVP with Apache License 2.0 6 votes vote down vote up
/**
 * 当 merge 和 zip 遇到  error 时改怎么办
 */
private void mergeAndZipOnError() {
    Observable<String> fail = Observable.create(emitter -> emitter.onError(new Throwable("obviously error")));

    Observable<Integer> success = Observable.create(emitter -> emitter.onNext(1));

    Disposable d = Observable.merge(fail, success)
            .subscribe((Consumer<Serializable>) serializable -> {
                if (serializable instanceof String) {

                }

            }, throwable -> Log.e(TAG, "accept: merge error " + throwable.getMessage()));

    d = Observable.zip(fail, success, (BiFunction<String, Integer, Object>)
            (s, integer) -> new String("success")).subscribe(o -> { },
            throwable -> Log.e(TAG, "accept: zip error " + throwable.getMessage()));
}
 
Example #16
Source File: Transformers.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
public static <A, B, C, K> FlowableTransformer<A, C> matchWith(final Flowable<B> b,
        final Function<? super A, K> aKey, final Function<? super B, K> bKey,
        final BiFunction<? super A, ? super B, C> combiner, int requestSize) {
    return new FlowableTransformer<A, C>() {

        @Override
        public Publisher<C> apply(Flowable<A> upstream) {
            return Flowables.match(upstream, b, aKey, bKey, combiner);
        }
    };
}
 
Example #17
Source File: StringsTest.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
@Test
public void testFromClasspath() {
    String expected = "hello world\nincoming message";
    assertEquals(expected, Strings.fromClasspath("/test2.txt").reduce(new BiFunction<String, String, String>() {
        @Override
        public String apply(String a, String b) {
            return a + b;
        }
    }).blockingGet());
}
 
Example #18
Source File: FlowableFetchPagesByRequestTest.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
@Test
public void testFetchByRequestError() {
    final BiFunction<Long, Long, Flowable<Integer>> fetch = new BiFunction<Long, Long, Flowable<Integer>>() {
        @Override
        public Flowable<Integer> apply(Long start, Long n) {
            throw new ThrowingException();
        }

    };
    Flowables.fetchPagesByRequest(fetch) //
            .test(1) //
            .assertNoValues() //
            .assertError(ThrowingException.class);
}
 
Example #19
Source File: BiFunctions.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
public static <T, R, S> BiFunction<T, R, S> toNull() {
    // TODO make holder
    return new BiFunction<T, R, S>() {

        @Override
        public S apply(T t1, R t2) throws Exception {
            return null;
        }
    };

}
 
Example #20
Source File: BiFunctions.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
public static <T, R, S> BiFunction<T, R, S> constant(final S value) {
    // TODO make holder
    return new BiFunction<T, R, S>() {

        @Override
        public S apply(T t1, R t2) throws Exception {
            return value;
        }
    };
}
 
Example #21
Source File: BiFunctions.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
public static <T extends Number> BiFunction<Statistics, T, Statistics> collectStats() {
    return new BiFunction<Statistics, T, Statistics>() {

        @Override
        public Statistics apply(Statistics s, T t) {
            return s.add(t);
        }
    };
}
 
Example #22
Source File: FlowableExampleActivity.java    From RxJava2-Android-Samples with Apache License 2.0 5 votes vote down vote up
private void doSomeWork() {

        Flowable<Integer> observable = Flowable.just(1, 2, 3, 4);

        observable.reduce(50, new BiFunction<Integer, Integer, Integer>() {
            @Override
            public Integer apply(Integer t1, Integer t2) {
                return t1 + t2;
            }
        }).subscribe(getObserver());

    }
 
Example #23
Source File: FlowableCollectWhile.java    From rxjava2-extras with Apache License 2.0 5 votes vote down vote up
CollectWhileSubscriber(Callable<R> collectionFactory,
        BiFunction<? super R, ? super T, ? extends R> add,
        BiPredicate<? super R, ? super T> condition, Subscriber<? super R> child,
        boolean emitRemainder) {
    this.collectionFactory = collectionFactory;
    this.add = add;
    this.condition = condition;
    this.child = child;
    this.emitRemainder = emitRemainder;
}
 
Example #24
Source File: NetworkingActivity.java    From RxJava2-Android-Samples with Apache License 2.0 5 votes vote down vote up
private void findUsersWhoLovesBoth() {
    // here we are using zip operator to combine both request
    Observable.zip(getCricketFansObservable(), getFootballFansObservable(),
            new BiFunction<List<User>, List<User>, List<User>>() {
                @Override
                public List<User> apply(List<User> cricketFans, List<User> footballFans) {
                    List<User> userWhoLovesBoth =
                            filterUserWhoLovesBoth(cricketFans, footballFans);
                    return userWhoLovesBoth;
                }
            })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<List<User>>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(List<User> users) {
                    // do anything with user who loves both
                    Log.d(TAG, "userList size : " + users.size());
                    for (User user : users) {
                        Log.d(TAG, "user : " + user.toString());
                    }
                }

                @Override
                public void onError(Throwable e) {
                    Utils.logError(TAG, e);
                }

                @Override
                public void onComplete() {
                    Log.d(TAG, "onComplete");
                }
            });
}
 
Example #25
Source File: ScanExampleActivity.java    From RxJava2-Android-Samples with Apache License 2.0 5 votes vote down vote up
private void doSomeWork() {
    getObservable()
            // Run on a background thread
            .subscribeOn(Schedulers.io())
            // Be notified on the main thread
            .observeOn(AndroidSchedulers.mainThread())
            .scan(new BiFunction<Integer, Integer, Integer>() {
                @Override
                public Integer apply(Integer int1, Integer int2) {
                    return int1 + int2;
                }
            })
            .subscribe(getObserver());
}
 
Example #26
Source File: ReduceExampleActivity.java    From RxJava2-Android-Samples with Apache License 2.0 5 votes vote down vote up
private void doSomeWork() {
    getObservable()
            .reduce(new BiFunction<Integer, Integer, Integer>() {
                @Override
                public Integer apply(Integer t1, Integer t2) {
                    return t1 + t2;
                }
            })
            .subscribe(getObserver());
}
 
Example #27
Source File: RxJavaFragment.java    From AndroidQuick with MIT License 5 votes vote down vote up
private void testZip() {
    Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
        @Override
        public String apply(Integer a, String b) throws Exception {
            return a + b;
        }
    }).compose(RxUtil.applySchedulers()).subscribe(new Consumer<String>() {
        @Override
        public void accept(String o) throws Exception {
            Log.d(TAG, o);
        }
    });
}
 
Example #28
Source File: TakeUntilExampleActivity.java    From RxJava2-Android-Samples with Apache License 2.0 5 votes vote down vote up
@Override
protected void doSomeWork() {
    Observable<Long> timerObservable = Observable.timer(5, TimeUnit.SECONDS);
    timerObservable.subscribe(new ObserverAdapter<Long>() {
        @Override
        public void onComplete() {
            String print = " Timer completed";
            textView.append(print);
            textView.append(AppConstant.LINE_SEPARATOR);
            Log.d(TAG, print);
        }
    });

    getStringObservable()
            //Delay item emission by one second
            .zipWith(Observable.interval(0, 1, TimeUnit.SECONDS), new BiFunction<String, Long, String>() {
                @Override
                public String apply(String s, Long aLong) throws Exception {
                    return s;
                }
            })
            //Will receive the items from Strings observable until timerObservable doesn't start emitting data.
            .takeUntil(timerObservable)
            //We need to observe on MainThread because delay works on background thread to avoid UI blocking.
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(getObserver());
}
 
Example #29
Source File: ZipExampleActivity.java    From RxJava2-Android-Samples with Apache License 2.0 5 votes vote down vote up
private void doSomeWork() {
    Observable.zip(getCricketFansObservable(), getFootballFansObservable(),
            new BiFunction<List<User>, List<User>, List<User>>() {
                @Override
                public List<User> apply(List<User> cricketFans, List<User> footballFans) {
                    return Utils.filterUserWhoLovesBoth(cricketFans, footballFans);
                }
            })
            // Run on a background thread
            .subscribeOn(Schedulers.io())
            // Be notified on the main thread
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(getObserver());
}
 
Example #30
Source File: RxTiPresenterUtils.java    From ThirtyInch with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a transformer that will delay onNext, onError and onComplete emissions until a view
 * become available. getView() is guaranteed to be != null during all emissions, provided that this
 * transformer is only used on the application's main thread.
 * <p/>
 * If this transformer receives a next value while the previous value has not been delivered,
 * the previous value will be dropped.
 * <p/>
 * Use this operator when you need to show updatable data.
 *
 * @param <T>       a type of onNext value.
 * @param presenter the presenter waiting for the view
 * @return the delaying operator.
 */
public static <T> ObservableTransformer<T, T> deliverLatestToView(
        final TiPresenter presenter) {
    return new ObservableTransformer<T, T>() {
        @Override
        public ObservableSource<T> apply(final Observable<T> observable) {

            // make sure we never complete
            final Observable<T> source = observable.concatWith(Observable.<T>never());

            // The order of the sources is important here! We want the viewReady emission to be captured first so that any synchronous
            // source emissions are not skipped.
            // See https://github.com/ReactiveX/RxJava/issues/5325
            return Observable
                    .combineLatest(isViewReady(presenter), source,
                            new BiFunction<Boolean, T, ViewReadyValue<T>>() {
                                @Override
                                public ViewReadyValue<T> apply(final Boolean viewReady, final T t)
                                        throws Exception {
                                    return new ViewReadyValue<>(t, viewReady);
                                }
                            })
                    .flatMap(new Function<ViewReadyValue<T>, ObservableSource<T>>() {
                        @Override
                        public ObservableSource<T> apply(final ViewReadyValue<T> viewReadyValue)
                                throws Exception {
                            if (viewReadyValue.viewReady) {
                                return Observable.just(viewReadyValue.value);
                            } else {
                                return Observable.empty();
                            }
                        }
                    });
        }
    };
}