📜 ⬆️ ⬇️

MVP and Dagger 2 - Skeleton Android Application - Part 1

This article is aimed at newcomers to Android development and is designed to help create the minimum necessary application structure.

It so happened that I relatively recently started programming for Android - after a month without a project in the company where I work, I was assigned to the mobile development team in the Tata Consultancy Services Uruguayan office. When talking with the team lead team, I was voiced by the stack, which I had to first become acquainted with and then master. Among other things, there was the Dagger 2 framework for DI and MVP as an architectural pattern. And Kotlin. But about him another time :)

Thus, I began to learn first the basics of the Android SDK, and then the entire companion stack. There were no problems with the SDK itself - there is more than enough comprehensive information about it on the network, starting with official documentation and ending with tutorials (especially the startandroid project helped), but with Dagger 2 and MVP there was some difficulty regarding Android development documentation of the first and, at that time, insufficient understanding of the second. The fact is that before mobile development, I did Java microservices using Spring Boot / MVC and already had a good idea of ​​what Dependency Injection is and what MVC is. Moreover, even the name “Spring MVC” itself suggests that this pattern is embedded in the architecture of the project and its use is obvious. From Dagger 2, I expected it to be the same as in Spring “magic” and as elaborate documentation and tutorials. And broken off: P

However, with sufficient perseverance and perseverance, nothing is impossible, and the result of the research was the implementation of my long-standing idea, which arose back in the days when I did not even think about Android development. You can rate the idea by installing the application from Google Store
')
In this article, I would like to present a dry squeeze of the result of my search - a step-by-step guide to creating a skeleton of an Android application using MVP and Dagger 2. So, let's begin.

1.1 Abstracts


First of all, let's create an abstracts package in the project root, let it be com.caesar84mx.mymvcapp.abstracts. We will create 2 interfaces in it: view.BaseView and presenter.BaseMvpPresenter. In the following way:



These are the basic architectural elements that will later be used in the application. Next, open BaseView and declare the showView () getContext () methods in it:

interface BaseView { fun showView(view: View, isShown: Boolean) { view.visibility = if (isShown) View.VISIBLE else View.GONE } fun getContext(): Context } 

Now open BaseMvpPresenter and edit it as follows:

 interface BaseMvpPresenter<V: BaseView> { var isAttached: Boolean fun attach(view: V) fun detach() } 

In the view package, we create the abstract class BaseCompatActivity, inherit it from AppCompatActivity and implement the newly created BaseView interface. Inside the class, we declare an abstract init method (savedInstanceState: Bundle?) And implement the getContext () method from BaseView:

 abstract class BaseCompatActivity: AppCompatActivity(), BaseView { override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) init(savedInstanceState) } protected abstract fun init(savedInstanceState: Bundle?) override fun getContext(): Context = this } 

From this class in the future we will inherit all the activity.

Now let's move on to the presenter - create a BasePresenter class that implements the BaseMvpPresenter interface and implement the interface methods as follows:

 open class BasePresenter<V : BaseView> : BaseMvpPresenter<V> { protected var view: V? = null private set override var isAttached = view != null override fun attach(view: V) { this.view = view } override fun detach() { this.view = null } } 

Great, we have defined the basic architectural elements, now let's move on to the components from which our application will be built.

1.2. Components


First of all, let's create the com.caesar84mx.mymvcapp.components package, the mainscreen package in it, in which, in turn, the ui and backstage packages, and transfer the MainScreen class to the ui package:



Now, we remove from the MainScreen class the implementation of the onCreate () method, which is automatically generated during the creation of the project, as well as inheritance from AppCompatActivity and inherit from BaseCompatActivity. Now we will implement the init () method previously declared in the base class. All the code that we would have previously placed in the onCreate () method, we put in it (as we remember, the init () method is called in the base class’s onCreate () method):

 class MainScreen : BaseCompatActivity() { override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) } } 

Great, the view element of the MVP pattern is created, now let's move to the backstage of our component - the backstage package. Create the interface MainScreenContract - the so-called contract, through which we will implement our pattern. In this interface we will create 2 subinterfaces - Presenter and View:

 interface MainScreenContract { interface Presenter: BaseMvpPresenter<MainScreenContract.View> interface View: BaseView } 

Now, let's move on to the pretner and create the MainScreenPresenter class:

 class MainScreenPresenter : BasePresenter<MainScreenContract.View>(), MainScreenContract.Presenter { } 

Skeleton application is almost ready, there are a few strokes. In the MainScreen class, add the implementation of the MainScreenContract.View interface, create and initialize the presenter: MainScreenPresenter variable, and in the init () method, attach the view to the presenter as follows:

 class MainScreen : BaseCompatActivity(), MainScreenContract.View { val presenter: MainScreenPresenter? = MainScreenPresenter() override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) presenter?.attach(this) } } 

Thus, we created a presenter and added our view instance (not to be confused with android.view.View), which in the presenter will be used for manipulating the view.

1.3. Conclusion of the first part


So, we have created the basic abstract elements of the MVP pattern, which, however, are not used directly, head-on, but through the so-called A contract is a basic element of each component of an application that combines both the actions of the view element and the actions of the presenter element. A contract is a fairly flexible element, the composition of which varies from component to component, unobtrusively linking components within a single architecture.

It should be remembered that, in accordance with the concept of MVP, the view element should be as stupid as possible; we only perform elementary actions in it, such as, for example, show / hide text, change the background or text color, show / hide the download icon, etc. d. We define the methods corresponding to this element in the subinterface View of the contract. While we are engaged in logic in the presenter - business logic, data manipulation (CRUD), running background tasks, etc. In it, we decide when and to show certain elements on the screen. This is in contrast to the MVC concept implemented in the spring, where between a business logic and a view there is a dumb controller that only receives requests from the view and calls a service that returns data or performs other actions defined by business logic. We define the methods corresponding to the presenter in the subinterface Presenter of the contract.

When implementing a presenter, views will be manipulated through the view variable of the BasePresenter superclass, while the methods corresponding to the view are implemented in the activity class.

You ask, where is Dagger 2 here and why did it give up to us? Wouldn't the DI implementation on Android be dragging the owl on the globe? The answer to the second question is no, it won't. And why and why it is needed - in the second part of my article;)

Source: https://habr.com/ru/post/434498/


All Articles