1. 前言
在几个月前,google sample组织下,创建了一个叫做android-architecture的仓库,第一时间引爆了Android圈,这个项目在于指导使用不同的架构指导我们如何解决测试、维护以及扩展的难题,让我们一一学习下。
2. todo-mvp分支
在去年的时候,mvp火了起来,然而,在国内的文章当中,大多是的试讲m-v-p分开来写,我今年毕设使用这种模式,发现一个很严重的问题,v-p之间关系较弱,难以管理。
好吧,让我们切到todo-mvp分支,一探究竟。
3. todo-mvp 模式图
引用自todo-mvp分支。
很明显,和我们以往看到的图略有区别。
- 最不同的地方在与model层,这里将model层用Repository(仓库)的概念来描述,分为远程数据源和本地数据源,还有内存部分,对应于网络、本地、内存三部分。
- 其实是vp层,这里将Activity作为vp层的载体
- 最后是view层,用Fragment来实现view层,而根据readme来看,使用Fragment的原因有两点
- activity和Fragment的分离非常适合MVP,activity起着创建和关联view和presenter的作用
- 平板电脑xxx 略过
接下来,让我们看看代码中有那些非常巧妙的地方。
4. 整体代码
今天,我们以tasksdetail为例,探索其中奥妙。主要代码目录结构如下:
- data 数据部分,主要为model层
- tastdetail
- TaskDetailActivity vp
- TaskDetailContract vp之间的契约关系
- TaskDetailFragment view的实现部分
- TaskPresenter p层实现
- Util 工具
- Basexxx 基类
我们先看Base基类。
在BaseView接口中,只有一个setPresenter的方法,这个方法,使用来给V注入P的。
在BasePresenter中,只有一个start方法,使用来在初始化及建立联系之后,做一些额外的初始化操作,如初始化数据等等。
5. vp的契约 Contract
以往的MVP模式,VP接口隔离起来,而现在,就爱那个VP写在一起,这样更加的清晰,至少不用找来找去。
在TaskDetailContract之中,内置了对应的View接口以及Presenter接口。代码我这里就不贴了,大家可以自己看看。
6. Activity是如何创建和联系VP的
相关代码如下。
- 创建View,通过实例Fragment,这里的Fragment是实现了View接口的。
创建Presenter,实例Presenter,但让,这里通过参数的形式来注入View,从而在Presenter的构造方法中,通过setPresenter的方法来建立联系。如图
当然,从MVP的思想知道,P是沟通model和view的桥梁,一次,我们在初始化的时候,Model层对应的Repository也是作为参数传递进去的。
而在Fragment实现的View的setPresenter方法中,只是将presenter赋值给了Fragment的成员变量,仅此而已。
那么,接下来,我们就来看看Presenter层是如何工作的。
7. Presenter是如何工作的
以下面这段代码为例。
从代码中我们能够看出,Presenter层调用Model层(Repository)去获取数据,并且根据需要返回结果(这里通过回调的方式),然后在根据结果,通过View去更新我们的UI。
8. Model层
Model层对应的数据的处理,从开头的图我们可以知道,在todo-mvp中,分为远程数据源、本地数据源或许还有(内存中的)。当然,从目录结构看也是这样子的。先看下结构。
除实体类外,以下非常重要。
- TasksDataSource 对应的操作方法(增删改查等等)以及回调接口(结果)
- TasksRepository 实现了TasksDataSource,负责管TasksRemoteDataSource和TasksLocalDataSource以及数据处理策略(网络、本地还是其他)
- TasksRemoteDataSource 实现了TasksDataSource,对应远程相应数据处理
- TasksLocalDataSource 实现了TasksDataSource,对应本地数据处理
以7代码中的getTask为例。我们看看他的实现。
代码的逻辑是这样的,
- getTaskWithId 从内存中取,取到则回调
- mTaskLocalDataSource,从local获取
- 取到 回调
- 没取到 mTasksRemoteDataSource ,从远程数据取(网络)
- 取到,回调
- 没取到,回调对应的失败方法
思路很清晰。
9. 总结
从todo-mvp中,我们能学到很多东西,在这里,虽然我只写下了这些,但是,todo-mvp中的测试、mock相关的部分,同样值得我们去学习。(ps:虽然到现在都没怎么关注过测试与mock)