Ali Abozaid
5 min readApr 18, 2016

Android clean code architecture

In the last two months I was searching for the best practices for architecting my app cause I face many problems with MVP that I used to use.

1. I was forced to set my network calls in my view(Activity or Fragment).

2. It’s hard to write your unit test to it cause there is no input or output ( actually I wasn’t writing unit test in this period ;) ).

3. It’s hard to change your code.

So I searched if there are any other architectures and I found Clean Code Architecture. And I started to search for android articles that implement this architecture and I found these two articles (first and second) and it took me a while to understand the whole architecture and after I understood the architecture, I was thinking about writing this post to simplify to devs who want to start implementing it and this post is based on the previous articles.

Before you start you should see this Robert C. Martin video.

Objectives of the clean code architecture

1. Separate the code into Layers that the inner layer doesn’t know anything about the outer layer(so we use dependency injection design pattern).

2. More optimization to your code and make your code easy to test.

Android Architecture

The architecture consists of four layers:

1. Entity (this represents your models).

2. Use Case (this represents your interactors).

3. Converters (this represents your presenters).

4. UI (this represents your activity and fragments).

Project architecture

1. domain (this contains your use cases and entities).

I. models.

II. interactors.

III. executors if exist.

IIII. modules if exist.

2. presentation ( this contains your ui and presenters).

I. ui.

I. activities.

II. fragments.

III. adapters.

II. presenters.

Let’s discuss each layer in details.

Presenters layer.

This layer acts as a converter that the ui layer asks for doing stuff and it starts doing it(by calling the interactor) and then convert the response to the form that the ui layer expect to receive.

Interactor layer

This layer is our use case layer and in this layer we do our logic (like get data from server or database) and get back the result to Presenters layer.

Entity layer

This represents your models in the app.

Let’s start! Code is here.

At first with our main presenter interface that all our presenters will implement!

public interface MainPresenter extends LifeCyclePresenter {public interface PresenterCallBack {void showLoading(boolean show);void showConnectionError(Throwable t);void updateView(Object data);}}

Which contain a callback interface (PresenterCallBack) that we will implement in our activity to get our result., if our request becomes success or failure and another method to show loading or our data.

I know you wanna ask about (LifeCyclePresenter) in this presenter we gonna mimic our life cycle cause as we agreed, the inner couldn’t know anything about the outer layer.

public interface LifeCyclePresenter {/*** Method that control the lifecycle of the view. It should be called in the view’s* (Activity or Fragment) onStart() method.*/void onStart();/*** Method that control the lifecycle of the view. It should be called in the view’s* (Activity or Fragment) onCreate() method.*/void onCreate();/*** Method that control the lifecycle of the view. It should be called in the view’s* (Activity or Fragment) onResume() method.*/void onResume();/*** Method that control the lifecycle of the view. It should be called in the view’s* (Activity or Fragment) onPause() method.*/void onPause();/*** Method that control the lifecycle of the view. It should be called in the view’s* (Activity or Fragment) onStop() method.*/void onStop();/*** Method that control the lifecycle of the view. It should be called in the view’s* (Activity or Fragment) onDestroy() method.*/void onDestroy();}

And our presenter will implement our MainPresenter as we agreed that each presenter will override it and we will implemment another ResponseCallback which exists in our interactor layer and i will disccuss it later.

public class ProductsPresenterImpl implements MainPresenter, ResponseCallback.MYCallback {PresenterCallBack presenterCallBack;ResponseCallback responseCallback;public ProductsPresenterImpl(Retrofit retrofit, String url, PresenterCallBack presenterCallBack) {this.presenterCallBack = presenterCallBack;responseCallback = new ProductsInteractorImpl(retrofit, url, this, presenterCallBack);}@Overridepublic void success(Object data) {presenterCallBack.updateView(data);}@Overridepublic void error(Throwable t) {presenterCallBack.showConnectionError(t);}@Overridepublic void onStart() {}@Overridepublic void onCreate() {}@Overridepublic void onResume() {}@Overridepublic void onPause() {}@Overridepublic void onStop() {}@Overridepublic void onDestroy() {responseCallback.unsubscribe();}}

And as you see the interactor get back our result in two methods either success or failure and our converter convert it to the form that our ui will expect (updateView(object), showConnectionError(thrawable))

Second: our interactors

Our first interactor that all interactors should implement is ResponseCallback that will get back our result to the presenter.

public interface ResponseCallback {void unsubscribe();interface MYCallback {public void success(Object data);public void error(Throwable t);}}

And our second interactor is our subscriber class that each interactor should adapt to it’s response model.

public class DefaultSubscriber<T> extends rx.Subscriber<T> {@Overridepublic void onCompleted() {// no-op by default.}@Overridepublic void onError(Throwable e) {// no-op by default.}@Overridepublic void onNext(T t) {// no-op by default.}}

And the third is the interactor that will execute our subscriber

public abstract class UseCase {private Subscription subscription = Subscriptions.empty();protected abstract Observable buildUseCaseObservable();public void execute(Subscriber UseCaseSubscriber) {this.subscription = this.buildUseCaseObservable().subscribeOn(Schedulers.io()) // or your executor.observeOn(AndroidSchedulers.mainThread()) //or your callback thread.subscribe(UseCaseSubscriber);}/*** Unsubscribes from current {@link rx.Subscription}.*/public void unsubscribe() {if (!subscription.isUnsubscribed()) {subscription.unsubscribe();}}}

And our implementation will look like

public class ProductsInteractorImpl extends UseCase implements ResponseCallback {private ResponseCallback.MYCallback mCallback;MainPresenter.PresenterCallBack presenterCallBack;ProductController products;String url;public ProductsInteractorImpl(Retrofit retrofit, String url, ResponseCallback.MYCallback mCallback, MainPresenter.PresenterCallBack presenterCallBack) {this.mCallback = mCallback;this.presenterCallBack = presenterCallBack;this.url = url;products = retrofit.create(ProductController.class);this.execute(new ProductSubscriber());}@Overrideprotected Observable buildUseCaseObservable() {return this.products.getProducts(url, BuildConfig.LIMIT, “json”);}@RxLogSubscriberprivate final class ProductSubscriber extends DefaultSubscriber<ListOfProductsModel> {@Overridepublic void onCompleted() {presenterCallBack.showLoading(false);}@Overridepublic void onError(Throwable e) {mCallback.error(e);}@Overridepublic void onNext(ListOfProductsModel listOfProductsModel) {mCallback.success(listOfProductsModel);}}}

This will return data to the interactor that will return it to our ui.

Testing

With this architecture we can fake our response from interactor to presenter and from presenter to our ui and test it without running our emulator

@Beforepublic void intialize(){presenterCallBack = this;throwable = new Throwable(“my error”);listOfProductsModel = new ListOfProductsModel();listOfProductsModel.feed = new ListOfProductsModel().new Feed();listOfProductsModel.feed.author = new ListOfProductsModel().new Feed().new Author();listOfProductsModel.feed.author.uri = new ListOfProductsModel().new Feed().new Author().new Uri();listOfProductsModel.feed.author.uri.label = “test”;}@Testpublic void productSuccessSubscriberCalled(){presenterCallBack.success(listOfProductsModel);}@Testpublic void productErrorSubscriberCalled(){presenterCallBack.error(throwable);}@Overridepublic void success(Object data) {assertNotNull(data);assertEquals(listOfProductsModel, data);}@Overridepublic void error(Throwable t) {assertNotNull(t);assertEquals(t, throwable);}

That’s it if you see something wrong or you want to ask about anything I’m glad to see your comment.

Source code

Grability.

Links and Resources

  1. The Clean Architecture.
  2. Uncle pop.
  3. A detailed guide on developing Android apps using the Clean Architecture pattern.
  4. Architecting Android…The clean way.

Dependencies

This repo depends on the following:

  1. Dagger2.0
  2. Retrofit2.0.0-beta4
  3. Rxjava:1.0
  4. Picasso2.5.2
  5. Butterknife7.0.1
  6. frodo0.8.2

Sample Video