In the context: news aggregator on Android with a backend. Android development: architecture development
Introductory part (with links to all articles)
In the water article, I already wrote that the planned client for the project should be the Android client: accessible to a large audience, easy, functional, beautiful, fast (not an application, but a dream!). If everything is clear with the grounds for choosing a platform, then far from everything was clear on how to implement all of the above requirements on the basis of it.
Previously, I didn’t do Android development, so for me rather valuable sources of information were:
After studying the indicated sources of questions with the architecture of Android and the interaction of their components, there were no more. However, one crucial question remained: what will be the structure of the application itself? A couple of examples and prototypes showed that with the growth of functionality, everything quickly began to turn into "noodles":
It became clear that you need to take a step back and look around: Android has been around for several years, there are people who have been developing code for this platform for a long time, there are large developing projects - accordingly there is where to get information about well-established practices.
The main criteria in finding a good architecture for an Android application were:
The search led me to an interesting video on YouTube: “We are writing a test code” (recording Evgeni Matsyuk (a) speech from the Mobius conference on mobile development) (there was MUCH ALL!) That described what I needed. For implementation it was required to study some additional resources and tools:
The development of a prototype with these practices in conjunction with the study of RxJava took a lot of time, but after a while the first prototype was ready. A distinctive feature of it was the terrible amount of created interfaces and classes when adding new screens: 3 interfaces and 3 classes (Activity / Fragment and its interface, Presenter and its interface, Interactor and its interface) - a classic example of overengineering. Formally, by the current moment, nothing has changed, but I think this is the flip side of the benefits. But the output is an easily tested application with a loosely coupled structure.
I will cite the Clean Architecture components from the article on Habr “Misconceptions of Clean Architecture” for refreshment .

Each Android component and element of the selected architecture is presented in the following table:
The interaction of components and data transfer is organized taking into account the fact that the user of any Android application receives more data than enters them. Respectively:
In the original article by Fernando Cejas, there were 2 options for organizing “by level” and “by functional”, I developed a combined approach for myself:
An interesting feature was the fact that the number of Interactors became equal to the “number of main screens” + “number of entities”: there are situations when you need to organize tricky data acquisition (for example, by combining from different sources) and copy this code to every Interactor, where it is required, was completely not wanted. Moreover, taking into account the fact that Interactor are used in a single copy - they can store some state important for the method execution, I implemented it as follows: Interactors of the screens turn to Interactors of entities for appropriate methods (which leads to the appearance of delegating methods in Interactor screens).
In terms of testing - nothing revolutionary:
Thanks for attention!
In the water article, I already wrote that the planned client for the project should be the Android client: accessible to a large audience, easy, functional, beautiful, fast (not an application, but a dream!). If everything is clear with the grounds for choosing a platform, then far from everything was clear on how to implement all of the above requirements on the basis of it.
Previously, I didn’t do Android development, so for me rather valuable sources of information were:
- The book "Android Programming: The Big Nerd Ranch Guide" (familiarization with the translation from the publishing house "Peter" confirmed the previously existing principle: "you can read the original - read the original");
- Google development site for Android;
- The book "Efficient Android Threading" from the publisher O'Reilly;
- Video from the Yandex project "Mobilization".
After studying the indicated sources of questions with the architecture of Android and the interaction of their components, there were no more. However, one crucial question remained: what will be the structure of the application itself? A couple of examples and prototypes showed that with the growth of functionality, everything quickly began to turn into "noodles":
- The logic of working with Android objects (Activity, Preferences, TextView ....) was mixed with business logic;
- Storage objects were featured in interface building code;
- Unit testing turned into hell because of the need to work with native Android objects and replace them with Robolectric instances ;
- Verification of the asynchronous code was possible only on the device or emulator (according to the principle: "launched-checked-repeated").
It became clear that you need to take a step back and look around: Android has been around for several years, there are people who have been developing code for this platform for a long time, there are large developing projects - accordingly there is where to get information about well-established practices.
The main criteria in finding a good architecture for an Android application were:
- easy testability of the developed code and its components - easy to test code is easy to develop and modify without fear to create a bug or “dump” the application;
- weak component cohesion, in which parts of the application / components can be developed by different developers without the need for super-intensive interaction (at least for some time).
The search led me to an interesting video on YouTube: “We are writing a test code” (recording Evgeni Matsyuk (a) speech from the Mobius conference on mobile development) (there was MUCH ALL!) That described what I needed. For implementation it was required to study some additional resources and tools:
- The original article “The Clean Architecture” , it is necessary to note the presence of a good explanatory article on the Habr “Misconceptions of Clean Architecture” ;
- Fernando Cejas Blog with Articles "Architecting Android ... The clean way?" and "Architecting Android ... The evolution" ;
- Dagger 2 ;
- RxJava .
The development of a prototype with these practices in conjunction with the study of RxJava took a lot of time, but after a while the first prototype was ready. A distinctive feature of it was the terrible amount of created interfaces and classes when adding new screens: 3 interfaces and 3 classes (Activity / Fragment and its interface, Presenter and its interface, Interactor and its interface) - a classic example of overengineering. Formally, by the current moment, nothing has changed, but I think this is the flip side of the benefits. But the output is an easily tested application with a loosely coupled structure.
Implementation
I will cite the Clean Architecture components from the article on Habr “Misconceptions of Clean Architecture” for refreshment .

Each Android component and element of the selected architecture is presented in the following table:
| Class | Level | Implementable Interfaces | Appointment |
| Implementation Activity / Fragment (XXXX_Activity / XXXX_Fragment) | UI | I_XXXX_View | Actual implementation of the action with Android elements: changing properties, receiving callbacks, starting services, working with the Android API |
| XXXX_PresenterImpl | UI | I_XXXX_Presenter | Coordination of presentation level actions, presentation logic - calls to interface methods I_XXXX_View, I_XXXX_Interactor |
| XXXX_InteractorImpl | Business / Use Cases | I_XXXX_Interactor | Implementation of the main application logic, calls to interface methods I_XXXX_Repository |
| XXXX_RepositoryImpl | Data / repository | I_XXXX_Repository | Implementing direct interaction with data sources, external APIs, the Android network and database, ContentProviders, etc. |
Organization of interaction
The interaction of components and data transfer is organized taking into account the fact that the user of any Android application receives more data than enters them. Respectively:
- signals are sent to deeper layers through regular synchronous calls (they pressed the button / scrolled / entered data -> called the method);
- receiving data from the lower layers is organized through asynchronous Rx-streams (received a call -> sent data with the results);
- synchronized data acquisition is minimized (most in the initialization code and in other auxiliary and rare screens).
Package organization
In the original article by Fernando Cejas, there were 2 options for organizing “by level” and “by functional”, I developed a combined approach for myself:
- Initially by levels (ui, data, business)
- In “ui” on the main screens “news_watcher”, “news_tape”, etc.
- In “data” and “business” - according to the main entities “news_header”, “news_article”, etc.
An interesting feature was the fact that the number of Interactors became equal to the “number of main screens” + “number of entities”: there are situations when you need to organize tricky data acquisition (for example, by combining from different sources) and copy this code to every Interactor, where it is required, was completely not wanted. Moreover, taking into account the fact that Interactor are used in a single copy - they can store some state important for the method execution, I implemented it as follows: Interactors of the screens turn to Interactors of entities for appropriate methods (which leads to the appearance of delegating methods in Interactor screens).
Initialization
- Activity / Fragment:
- created by Android (non-singletone, w / scope)
- initialized in methods View # onCreate () (with completion in Fragment # onViewCreated () for Fragment)
- Presenter internally assigned to D / Dagger2
- initialization of Presenter inside is done in the specified methods (View # onCreate (), with completion in Fragment # onViewCreated () for Fragment)
- Presenter:
- created via Dagger2 (non-singletone, w / scope)
- View is assigned by the View itself, via Presenter # bindView ()
- initialized in the method Presenter # initializePresenter (), called by View (because the initialization must be done at the right time, after the initialization of the View)
- Interactor internally assigned / initialized via Dagger2
- the creation of the Interactor-> Presenter relationship is performed in the Presenter # initializePresenter () method (through other Interactor methods for Rx initialization)
- Interactor:
- created via Dagger2 (singletone, w / o scope)
- initialized via Dagger2 (Interactor # initializeInteractor)
- Repository inside assigned / initialized via Dagger2
- Repository:
- created via Dagger2 (singletone, w / o scope)
- initialized via Dagger2 (Repository # initializeRepository)
Testing Approaches
In terms of testing - nothing revolutionary:
- UI Level - JUnit + Mockito + Robolectric
- Business Level - JUnit + Mockito
- Data level - JUnit + Mockito
Thanks for attention!