Handling a long task

We already know how to handle slow I/O operations. Let's see an example of a long, slow task that is not I/O-bound. For this example, we will modify our loadList() function and create a new slow function that will emit our installed apps' items:

private Observable<AppInfo> getObservableApps(List<AppInfo> apps) {
    return Observable
            .create(subscriber -> {
                for (double i = 0; i < 1000000000; i++) {
                    double y = i * i;
                }

                for (AppInfo app : apps) {
                    subscriber.onNext(app);
                }
                subscriber.onCompleted();
            });
}

As you can see, this function performs a few nonsensical computations, only to waste time for the sake of our example, and then it emits our AppInfo items from the List<AppInfo> object. Now, we can rearrange our loadList() function like this:

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

    getObservableApps(apps)
            .subscribe(new Observer<AppInfo>() {
@Override
public void onCompleted() {
mSwipeRefreshLayout.setRefreshing(false);
                    Toast.makeText(getActivity(), "Here is the  list!", Toast.LENGTH_LONG).show();
                }

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

@Override
public void onNext(AppInfo appInfo) {
mAddedApps.add(appInfo);
mAdapter.addApplication(mAddedApps.size() - 1, appInfo);
                }
            });
}

If we run this code, the app will get stuck the moment we click on the Navigation Drawer item, as you can perceive from the half-closed menu in the following figure:

Handling a long task

If we are unlucky, we can even see the classic ANR message shown in the next figure:

Handling a long task

For sure, we will see the following unpleasant message in logcat:

I/Choreographer﹕ Skipped 598 frames!  The application may be  doing too much work on its main thread.

The message is pretty clear: Android is telling us that the user experience will be poor because we are blocking the UI thread with an unnecessary workload. But we already know how to deal with this: we have Schedulers! We just have to add a couple more lines to our Observable chain to get rid of slowness and the Choreographer messages:

getObservableApps(apps)
        .onBackpressureBuffer()
        .subscribeOn(Schedulers.computation())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<AppInfo>() { […]

With these few lines, we will have a fast closing Navigation Drawer, a nice spinning progress bar, and a slow computational task, which is working on a separate thread and will return the results on the UI thread to let us update our installed apps list.

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

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