Join

The two previous methods, zip() and merge(), work in the domain of the emitted items. There are scenarios in which we have to also consider the time before deciding how to operate on values. RxJava's join() function combines items from two Observables, working with time windows.

Join

To properly understand the previous figure, let's explain which parameters join() takes:

  • The second Observable to combine with the source Observable
  • A Func1 parameter that returns an Observable that specifies a time span defining the time window during which the item emitted by the source Observable will interact with the items from the second Observable
  • A Func1 parameter that returns an Observable that specifies a time span defining the time window during which the item emitted by the second Observable will interact with the items from the source Observable
  • A Func2 parameter that defines how the emitted items will be combined together to emit a new item

As a practical example, we can modify our loadList() function like this:

private void loadList(List<AppInfo> apps) {
mRecyclerView.setVisibility(View.VISIBLE);

    Observable<AppInfo> appsSequence = Observable.interval(1000, TimeUnit.MILLISECONDS).map(position -> {
return apps.get(position.intValue());
            });
    Observable<Long> tictoc = Observable.interval(1000, TimeUnit.MILLISECONDS);

appsSequence
            .join(
tictoc, appInfo ->Observable.timer(2, TimeUnit.SECONDS),time ->Observable.timer(0, TimeUnit.SECONDS),this::updateTitle)
            .observeOn(AndroidSchedulers.mainThread())
            .take(10)
            .subscribe(new Observer<AppInfo>() {
@Override
public void onCompleted() {
Toast.makeText(getActivity(), "Here is the list!",  Toast.LENGTH_LONG).show();
                }

@Override
public void onError(Throwable e) {
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), "Something went wrong!",  Toast.LENGTH_SHORT).show();
                }

@Override
public void onNext(AppInfoappInfo) {
if (mSwipeRefreshLayout.isRefreshing()) {
mSwipeRefreshLayout.setRefreshing(false);
                    }
mAddedApps.add(appInfo);
intposition = mAddedApps.size() - 1;
mAdapter.addApplication(position, appInfo);
mRecyclerView.smoothScrollToPosition(position);
                }
            });
}

We have a new player on the field: appsSequence. This is an Observable sequence emitting apps from our installed apps list every second. The tictoc Observable item is just emitting a new Long item every second. Joining them, we specify two Func1 variables:

appInfo -> Observable.timer(2, TimeUnit.SECONDS)

and

time -> Observable.timer(0, TimeUnit.SECONDS)

These describe the two time windows. The following line describes how we are going to combine the emitted values using a Func2 variable:

this::updateTitle

As a result, we have:

Join

It looks a bit messy, but paying attention to the apps' names and the time windows we specified, we can see what's going on: we are combining the second item with the source item every time the second item is emitted, but we are using the same source item for 2 seconds. This is why the titles repeat themselves and the numbers add up.

It's worth mentioning, to lighten up the situation, that there is also a join() operator that works on strings and simply joins the emitted strings into one final string:

Join
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.35.185