Skip to content

magic-coder/android-architecture

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 

Repository files navigation

TODO-MVP-Loaders

It is based on the TODO-MVP sample and uses Loaders to get the data from the tasks repository.

Diagram

The advantages of Loaders, from the Loaders documentation page, are:

  • They provide asynchronous loading of data, removing the need for callbacks in the repository.
  • They monitor the source of their data and deliver new results when the content changes, in our case, the repository.
  • They automatically reconnect to the last loader when being recreated after a configuration change.

Code

Asynchronous loading

The Loaders (TaskLoader and TasksLoader) are responsible for fetching the data and extend AsyncTaskLoader.

In src/data/source/TasksLoader.java:

@Override
public List<Task> loadInBackground() {
    return mRepository.getTasks();
}

The results are received in the UI Thread, handled by the presenter.

In TasksPresenter.java

@Override
public void onLoadFinished(Loader<List<Task>> loader, List<Task>
data) {
    mTasksView.setLoadingIndicator(false);

    mCurrentTasks = data;
    if (mCurrentTasks == null) {
        mTasksView.showLoadingTasksError();
    } else {
        showFilteredTasks();
    }
}

The presenter also triggers the loading of data, like in the MVP sample but in this case it does it through the LoaderManager:

@Override
public void start() {
    mLoaderManager.initLoader(TASKS_QUERY, null, this);
}

Content observer

After every content change in the repository, notifyContentObserver() is called.

In src/data/source/TasksRepository.java:

@Override
public void deleteTask(@NonNull String taskId) {
    mTasksRemoteDataSource.deleteTask(checkNotNull(taskId));
    mTasksLocalDataSource.deleteTask(checkNotNull(taskId));

    mCachedTasks.remove(taskId);

    // Update the UI
   notifyContentObserver();
}

This notifies the Loader which in this case simply forces a reload of data.

In TasksLoader.java:

@Override
public void onTasksChanged() {
    if (isStarted()) {
        forceLoad();
    }
}

Additional dependencies

This project uses the Loaders framework available from Android 3.0 (API Level 11).

Features

Complexity - understandability

Use of architectural frameworks/libraries/tools:

No external frameworks.

Conceptual complexity

Developers need to be familiar with the Loaders framework, which is not trivial.

Testability

Unit testing

The use of the Loaders framework adds a big dependency with the Android framework so unit testing is harder.

UI testing

No difference with MVP.

Code metrics

Compared to MVP, the only new classes are TaskLoader and TasksLoader. Parts of the code are simpler as Loaders take care of the asynchronous work.

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Java                            48           1085           1444           3517 (3450 in MVP)
XML                             34             97            337            601
-------------------------------------------------------------------------------
SUM:                            82           1182           1781           4118
-------------------------------------------------------------------------------

Maintainability

Ease of amending or adding a feature

Similar to MVP

Learning cost

Medium as the Loaders framework is not trivial.

About

A collection of samples to discuss and showcase different architectural tools and patterns for Android apps.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published