本文针对Android开发的初学者,旨在帮助创建所需的最低限度的应用程序结构。
碰巧的是,我最近才开始为Android编程-在我工作的公司没有一个项目的一个月后,我被分配到塔塔咨询服务公司乌拉圭办事处的移动开发团队。 与团队负责人交谈时,我被告知需要首先熟悉自己,然后精通自己。 除其他外,还有用于DI和MVP的Dagger 2框架作为体系结构模式。 还有科特林。 但是关于他的另一次:)
因此,我开始研究Android SDK的基础知识,然后研究整个附带的堆栈。 SDK本身没有问题-网络上有足够的详尽信息,从官方文档开始到教程结束(尤其是startandroid项目对此提供了帮助),但是Dagger 2和MVP的Android开发存在一些困难,因为它的时间很短关于第一个的文档,当时对第二个的理解不足。 事实是,在进行移动开发之前,我使用Spring Boot / MVC在Java中进行了微服务,并且已经对什么是依赖注入以及什么是MVC有了很好的认识。 而且,甚至名称“ Spring MVC”本身也表明该模式已嵌入到项目体系结构中,并且其用途显而易见。 在Dagger 2中,我希望获得与Spring相同的“魔力”,并获得与之相同的详尽文档和教程。 并折断:P
尽管如此,有了足够的毅力和毅力,没有什么是不可能的,并且研究的结果是实现了我的长久想法,即使在我什至没有考虑过Android开发的那些日子里,也出现了我的想法。 您可以通过从Google Store安装应用程序来评估想法在本文中,我想简要介绍一下搜索结果-有关使用MVP和Dagger 2创建Android应用程序框架的逐步指南。因此,让我们开始吧。
1.1摘要
首先,在项目的根目录创建abstracts包,将其命名为com.caesar84mx.mymvcapp.abstracts。 我们将在其中创建2个接口:view.BaseView和presenter.BaseMvpPresenter。 如下:

这些是基础架构元素,以后将在应用程序中使用。 接下来,打开BaseView并在其中声明showView()getContext()方法:
interface BaseView { fun showView(view: View, isShown: Boolean) { view.visibility = if (isShown) View.VISIBLE else View.GONE } fun getContext(): Context }
现在打开BaseMvpPresenter并按如下所示进行编辑:
interface BaseMvpPresenter<V: BaseView> { var isAttached: Boolean fun attach(view: V) fun detach() }
在视图包中,创建一个抽象BaseCompatActivity类,从AppCompatActivity继承它,并实现新创建的BaseView接口。 在类内部,我们声明抽象的init方法(savedInstanceState:Bundle?),并从BaseView中实现getContext()方法:
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 }
将来,我们将从这一堂课继承所有活动。
现在,我们继续演示者-创建一个实现BaseMvpPresenter接口的BasePresenter类,并实现接口方法,如下所示:
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 } }
好了,我们已经确定了基本的架构元素,现在让我们继续构建应用程序所基于的组件。
1.2。 组成部分
首先,创建com.caesar84mx.mymvcapp.components程序包,在其中创建mainscreen程序包,在其中依次包含ui和backstage程序包,并将MainScreen类转移到ui程序包:

现在,我们将从MainScreen类中删除在创建项目时自动生成的onCreate()方法的实现,以及从AppCompatActivity的继承,并从BaseCompatActivity继承。 现在,我们实现先前在基类中声明的init()方法。 我们将之前放入onCreate()方法中的所有代码都放入了它(回想一下,init()方法在基类的onCreate()方法中被调用):
class MainScreen : BaseCompatActivity() { override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) } }
太好了,创建了MVP模式的view元素,现在让我们进入组件的后台-后台程序包。 让我们创建MainScreenContract接口-所谓的合同,通过它我们将实现我们的模式。 在此界面中,创建2个子界面-Presenter和View:
interface MainScreenContract { interface Presenter: BaseMvpPresenter<MainScreenContract.View> interface View: BaseView }
现在,让我们进入演示者并创建MainScreenPresenter类:
class MainScreenPresenter : BasePresenter<MainScreenContract.View>(), MainScreenContract.Presenter { }
应用程序框架几乎已准备就绪,仍然需要进行一些操作。 在MainScreen类中,添加MainScreenContract.View接口的实现,创建并初始化presenter变量:MainScreenPresenter,并在init()方法中,将视图附加到presenter上,如下所示:
class MainScreen : BaseCompatActivity(), MainScreenContract.View { val presenter: MainScreenPresenter? = MainScreenPresenter() override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) presenter?.attach(this) } }
因此,我们创建了一个演示者,并向其添加了我们的视图实例(不要与android.view.View混淆),该实例将在演示者中用于操作视图。
1.3。 第一部分结论
因此,我们已经创建了MVP模式的基本抽象元素,但是,这些不是直接在额头上使用,而是通过所谓的元素使用。 contract-应用程序每个组件的基本元素,它结合了view元素的动作和presenter元素的动作。 合同是一个相当灵活的元素,其组成因组件而异,在单一体系结构中毫不干扰地链接组件。
应当记住,按照MVP的概念,view元素应尽可能平淡,因为其中我们仅执行基本操作,例如显示/隐藏文本,更改文本的背景或颜色,显示/隐藏下载图标等。 d。 我们在View合同的子界面中定义与此元素相对应的方法。 虽然我们在演示者中处理逻辑-业务逻辑,数据处理(CRUD),启动后台任务等。 在其中,我们决定何时在屏幕上显示某些元素。 这与春季实现的MVC概念不同,后者在业务逻辑和视图之间有一个哑控制器,该哑控制器仅从视图接收请求并调用返回数据或执行业务逻辑定义的其他操作的服务。 与演示者相对应的方法在演示者合同的子界面中定义。
在实现演示者时,将通过BasePresenter超类的view变量来操纵视图,而与视图相对应的方法在活动类中实现。
您问,Dagger 2在哪里,为什么向我们投降呢,Android中的DI实现会否将猫头鹰推向世界? 第二个问题的答案是否定的,不是。 以及为什么以及为什么需要它-在我的文章的
第二部分中 ;)