Background data loading
– Android TV application hands on tutorial 15

LoaderManager_Loader

Background data loading using Loader class

This Tutorial was explaining about Leanback support library, which is usually used to show list of contents information. So developers may want to load a many meta data to show contents. When Activity or Fragment need to prepare big size of data, it is better to load the data in background.

For this purpose, we can use Loader and LoaderManager. They are useful to implement background data loading followed by updating UI based on these loaded data. I’m going to implement this Loader in this chapter. To study about Loader, I found a very nice article to understand Loader and the LoaderManager in detail (from part 1 to part 4). This post is a basic course, so please refer the above article for advanced understanding.

As a summary of the article, the advantage of using LoaderManagerLoader is

  • Data loading process can be independent from Activity lifecycle.
    • LoaderManager is Activity unique instance (singleton), which handles Loader‘s lifecycle like starting, stopping, reseting. By using Loader, loading process can be independent from Activity lifecycle. One of the most useful situation is when configuration change occurs by display rotation (this is for Android phone and not for Android TV), Activity will be destroyed but Loader‘s information retains.
  • UI thread, background thread handling is easy.
    • This is very similar to AsyncTask so that we can asynchronously prepare data in background thread and get callback to update UI on UI thread. It enables us to develop “good” software architecture easily, so that we can reduce the task of UI thread.
      (See also AsyncTask usage summary.)
  • Loader is Event-driven, data handling is easy & convenient.
    • For example, when data source changed, we can get callback. We can easily update UI according to data change.

To understand implementation we need to take care the relation between Activity/Fragment side and Loader side implementation.

Relationship between Activity, Loader and LoaderManager

 

LoaderManager_Loader

LoaderManager is Activity unique instance, and NOT system/application-wise unique instance. Therefore, it is not possible to use a data prepared in Loader A of Activity A from Activity B.

Hands on example: Minimum implementation

Let’s take a look at example of implementing Loader in MainFragment class. We need to implement 2 modules, Loader side which takes care of background data loading process and Activity side with LoaderManager.LoaderCallbacks which handles how to show data on UI.

Activity/Fragment side

1. We will register loader by getLoaderManger().initLoader(id, args, callback) where

  • id: Loader’s id. This should be identical in each Activity, it is ok to use same id number in different Activity because LoaderManager instance exists for each Activity/Fragment.

2. Implementation of LoaderManager.LoaderCallbacks, we need to override 3 methods.

  • onCreateLoader – We will instantiate Loader Here.
  • onLoadFinished – It will called when Loader finish preparing data, data will be shown on UI inside this method.
  • onLoaderReset – If data loading is unsuccessful or stops, this method will be called.

First, let’s implement initLoader in onActivityCreated and register LoaderManager.LoaderCallbacks. Then implement mock of Callbacks as follows.

return value of onCreateLoader method will be the instance of Loader. Now we are going to implement Loader side. 

Loader side

The Loader is specified as return value of onCreateLoader. I Created new class VideoItemLoader in data package, and extend AsyanTaskLoader<D> to start with.

At least 2 methods need to be implemented (Override).

  • Constructor – parent class, AsyncTaskLoader, requires context. Pass it in the constructor.
  • loadInBackground() – this is just like doInBackground() method of AsyncTask.

What you “must” implement is above two methods. But when I try it, loadInBackground() is never called with this implementation. I needed to implement forceLoad() method in 

  • onStartLoading()

to explicitly start Loading. Below is the code of these three methods implementation.

Data loading process has implemented. Finally, go back to Activity side to handle this data to show on UI.

Go back to Loader side

The last remaining task is to only implementing onLoadFinished callback. The argument is the loaded data coming from Loader

Build and run

loader

You can check the source code until here on github, but nothing much changed on UI since loader will do loading process in background. Loader‘s advantage appears when we need a background data loading process which may take long time. As one example of background data loading, I will introduce data loading from the Internet in Next chapter. 

Comments: Loader in another Activity

We have implemented Loader in MainFragment, and how about implementing Loader in another Activity/Fragment, for example VideoDetailsFragment. I thought it is nice if we could use same Loader instance with different Activity. Indeed both MainFragment and VideoDetailsFragment need same VideoList data! However it is very disappointing fact for me that we cannot share the instance of Loader among Activity/Fragment, since LoaderManager is not a system-wise singleton, but the instance (LoaderManagerImpl mLoaderManager) exists in each Activity/Fragment.

Then how should we manage data among between Activity? I think one way is to make an independent data manager class which keeps the instance of data. This is also done in next chapter.

Reference

Sponsored Links

3 responses

    • Hi Igor,
      I wanted to say that the same Loader instance cannot be shared with Activity A and Activity B.

      LoaderManager instance is existing for “each” Activity, in other words Activity A has an instance of LoaderManager and Activity B has another instance of LoaderManager.
      Since Loader instance is handled by LoaderManager, Loader instance also belongs to each Activity.

      If you want to know more detail, you can see source code of Activity class, there is getLoaderManager method. Its explanation is “Return the LoaderManager for this activity, creating it if needed.”, so LoaderManager instance is unique for each Activity.

      Is it answering your question?

Leave a Reply

Your email address will not be published.