rxjava's killer mace in android (1)

Solve button quick click

private PublishSubject<Boolean> eventSubject = PublishSubject.create();
    public static final int TIME_BETWEEN_EVENTS_MILLIS = 500;
    public static final int NUMBER_OF_EVENTS = 2;
    public DoubleClick() {
        eventSubject.buffer(eventSubject.debounce(TIME_BETWEEN_EVENTS_MILLIS, TimeUnit.MILLISECONDS))
                .filter(events -> events.size() == NUMBER_OF_EVENTS)
                .subscribe(events -> doSomething());

        button.setOnClickListener((button) -> eventSubject.onNext(true));
    }

By using Publish Subject, we can send and capture click events and filter repeated click events per unit time interval. Of course, this approach can be applied to any event. For example, if a search input box needs to execute search logic based on the user's keyword input, it can be used in Text Changed events to avoid the user continually executing search logic in the process of keyword input.

Perform API requests every 10 minutes

sourceObservable.repeatWhen(completed -> completed.delay(10, TimeUnit.MINUTES));

Note, however, that the repeatWhen operator repeats only after Observable sends the onComplete event, otherwise use retryWhen( The difference between retryWhen and repeatWhen operators)

Combining two dependent types with flatmap operators

For example, we get User Order logic: first we get App Token, then we get User Token according to App Token, and finally we get User Order according to App Token and User Token.

Observable<Order> orderObservable =
                getAppTokenObservable()
                        .flatMap((appToken) -> geUserTokenObservable(appToken),
                                (appToken,userToken) -> getOrder(appToken,userToken));

Paging request data

If the paging request is based on the flag returned from the current page to request the next page, rxjava can help you deal with the paging logic. Specific practice is: according to the paging mark, in the absence of the end of the paging mark, directly request the next page of data, and the results and the previous page of data merge, continue to do so until the end of the paging mark.

public Observable<List<User>> getAllUsers() {
    //Request a page of data, according to your API design, not necessarily pass null
    return getUsersObservable(null);
}
private Observable<List<User>> getUsersObservable(final String lastUserId) {
    return apiAdapter.getData(lastUserId)
            .filter(userList -> !isLastPage(userList))
            .flatMap(this::getNextPageUsersObservable);
}
private Observable<List<User>> getNextPageUsersObservable(final List<User> userList) {
    Observable<List<User>> usersPageObservable = Observable.just(userList);
    int lastUserId = getLastUserId(userList);
    Observable<List<User>> nextUsersPageObservable = getUsersObservable(lastUserId);
    return Observable.merge(nextUsersPageObservable, usersPageObservable);
}
private boolean isLastPage(final List<User> userList) {
    return userList.isEmpty();
}

Lightweight rxbus

public class RxBus {

    private static final RxBus instance = new RxBus();
    private final Subject<RxEvent> rxBus;

    public RxBus() {
        PublishSubject<RxEvent> rxEventPublishSubject = PublishSubject.create();
        rxBus = rxEventPublishSubject.toSerialized();
    }

    public static RxBus getInstance() {
        return instance;
    }

    public Observable<RxEvent> getRxBus() {
        return rxBus;
    }

    public void post(final RxEvent rxEvent) {
        rxBus.onNext(rxEvent);
    }

    public class RxEvent {
    }
}

The difference between Serialized Subject and Publish Subject is that Serialized Subject is thread-safe.

Added by chadowch on Fri, 05 Jul 2019 00:25:34 +0300