Este artículo está dirigido a principiantes en el desarrollo de Android y está diseñado para ayudar a crear la estructura de aplicación mínima requerida.
Sucedió que relativamente recientemente comencé a programar para Android: después de un mes sin un proyecto en la empresa donde trabajo, me asignaron al equipo de desarrollo móvil en la oficina uruguaya de Tata Consultancy Services. Cuando hablé con el líder del equipo, se me expresó una pila con la que primero tenía que familiarizarme y luego dominar. Entre otras cosas, estaba el marco Dagger 2 para DI y MVP como patrón arquitectónico. Y Kotlin. Pero sobre él en otra ocasión :)
Entonces, comencé a estudiar primero los conceptos básicos del SDK de Android, y luego toda la pila que lo acompaña. No hubo problemas con el SDK en sí mismo: hay información exhaustiva más que suficiente en él en la red, comenzando con documentación oficial y terminando con tutoriales (el proyecto startandroid ayudó especialmente con esto), pero hubo algunas dificultades con Dagger 2 y MVP con respecto al desarrollo de Android debido a un poco más documentación de la primera y, en ese momento, comprensión insuficiente de la segunda. El hecho es que antes del desarrollo móvil hice microservicios en Java usando Spring Boot / MVC y ya tenía una buena idea sobre qué es la inyección de dependencia y qué es MVC. Además, incluso el nombre "Spring MVC" sugiere que este patrón está incrustado en la arquitectura del proyecto y su uso es obvio. De Dagger 2 esperaba la misma "magia" que en Spring y la misma documentación elaborada y tutoriales. Y se interrumpió: P
Sin embargo, con suficiente perseverancia y perseverancia, nada es imposible, y el resultado de la investigación fue la implementación de mi antigua idea que surgió incluso en aquellos días en que ni siquiera pensaba en el desarrollo de Android. Puede evaluar la idea instalando la aplicación desde Google StoreEn este artículo, me gustaría presentar un pequeño resumen del resultado de mis búsquedas: una guía paso a paso para crear el esqueleto de una aplicación de Android usando MVP y Dagger 2. Entonces, comencemos.
1.1 Resúmenes
Primero, cree el paquete de resúmenes en la raíz del proyecto, deje que sea com.caesar84mx.mymvcapp.abstracts. Crearemos 2 interfaces en él: view.BaseView y presentador.BaseMvpPresenter. Como sigue:

Estos son los elementos arquitectónicos básicos que luego se utilizarán en la aplicación. A continuación, abra BaseView y declare los métodos showView () getContext () en él:
interface BaseView { fun showView(view: View, isShown: Boolean) { view.visibility = if (isShown) View.VISIBLE else View.GONE } fun getContext(): Context }
Ahora abra BaseMvpPresenter y edítelo de la siguiente manera:
interface BaseMvpPresenter<V: BaseView> { var isAttached: Boolean fun attach(view: V) fun detach() }
En el paquete de vista, cree una clase abstracta BaseCompatActivity, herede de AppCompatActivity e implemente la interfaz BaseView recién creada. Dentro de la clase, declaramos el método init abstracto (savedInstanceState: Bundle?) E implementamos el método getContext () desde 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 }
De esta clase en el futuro heredaremos todas las actividades.
Ahora pasemos al presentador: cree una clase BasePresenter que implemente la interfaz BaseMvpPresenter e implemente los métodos de interfaz de la siguiente manera:
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 } }
Bueno, hemos identificado los elementos arquitectónicos básicos, ahora pasemos a los componentes a partir de los cuales se construirá nuestra aplicación.
1.2. Componentes
Primero, cree el paquete com.caesar84mx.mymvcapp.components, en él el paquete mainscreen, en el que, a su vez, los paquetes ui y backstage, y transfiera la clase MainScreen al paquete ui:

Ahora eliminaremos de la clase MainScreen la implementación del método onCreate () generado automáticamente cuando se creó el proyecto, así como la herencia de AppCompatActivity y la heredaremos de BaseCompatActivity. Ahora implementamos el método init () previamente declarado en la clase base. Todo el código que pondríamos en el método onCreate () anteriormente, lo ponemos (como recordamos, el método init () se llama en el método onCreate () de la clase base):
class MainScreen : BaseCompatActivity() { override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) } }
Genial, se crea el elemento de vista del patrón MVP, ahora pasemos al backstage de nuestro componente: el paquete backstage. Creemos la interfaz MainScreenContract, el llamado contrato a través del cual implementaremos nuestro patrón. En esta interfaz, cree 2 subinterfaces: Presentador y Vista:
interface MainScreenContract { interface Presenter: BaseMvpPresenter<MainScreenContract.View> interface View: BaseView }
Ahora, pasemos al presentador y creemos la clase MainScreenPresenter:
class MainScreenPresenter : BasePresenter<MainScreenContract.View>(), MainScreenContract.Presenter { }
El esqueleto de la aplicación está casi listo, quedan algunos toques. En la clase MainScreen, agregue la implementación de la interfaz MainScreenContract.View, cree e inicialice la variable presentadora: MainScreenPresenter, y en el método init (), adjunte la vista al presentador de la siguiente manera:
class MainScreen : BaseCompatActivity(), MainScreenContract.View { val presenter: MainScreenPresenter? = MainScreenPresenter() override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) presenter?.attach(this) } }
Por lo tanto, creamos un presentador y le agregamos nuestra instancia de vista (que no debe confundirse con android.view.View), que en el presentador se utilizará para manipular la vista.
1.3. Conclusión de la primera parte.
Entonces, hemos creado los elementos abstractos básicos del patrón MVP, que, sin embargo, no se usan directamente, en la frente, sino a través de los llamados. contrato: el elemento básico de cada componente de la aplicación, que combina las acciones del elemento de vista y las acciones del elemento presentador. Un contrato es un elemento bastante flexible, cuya composición varía de un componente a otro, vinculando discretamente los componentes dentro de una sola arquitectura.
Debe recordarse que de acuerdo con el concepto de MVP, el elemento de vista debe ser lo más contundente posible, en él realizamos solo acciones elementales, como, por ejemplo, mostrar / ocultar texto, cambiar el fondo o el color del texto, mostrar / ocultar el icono de carga, etc. d. Definimos los métodos correspondientes a este elemento en la subinterfaz del contrato Ver. Mientras tratamos la lógica en un presentador: lógica de negocios, manipulación de datos (CRUD), lanzamiento de tareas en segundo plano, etc. En él, decidimos cuándo mostrar ciertos elementos en la pantalla. Esto es diferente del concepto MVC implementado en la primavera, donde entre la lógica de negocios y la vista hay un controlador tonto que solo recibe solicitudes de la vista y llama a un servicio que devuelve datos o realiza otras acciones definidas por la lógica de negocios. Los métodos correspondientes al presentador se definen en la subinterfaz del contrato del presentador.
Al implementar el presentador, la vista se manipulará a través de la variable de vista de la superclase BasePresenter, mientras que los métodos correspondientes a la vista se implementan en la clase de actividad.
Usted pregunta, ¿dónde está Dagger 2 aquí y por qué se entregó a nosotros? ¿La implementación de DI en Android arrastrará una lechuza al mundo? La respuesta a la segunda pregunta es no, no lo hará. Y por qué y por qué es necesario, en la
segunda parte de mi artículo;)