[译]Google官方关于Android架构中MVP模式的示例
概述
该示例(TODO-MVP)是后续各种示例演变的基础,它主要演示了在不带架构性框架的情况下实现M-V-P模式。其采用手动依赖注入的方式来提供本地数据源和远程数据源仓库。异步任务通过回调处理。

注意:MVP中View的概念是有所不同的:
- android.view.View类我们叫它 "Android View"
- MVP中从P接收命令的东西我们叫它”View”,后文说了,就是Fragment
Fragment
采用Fragment作为视图的载体有两个原因:
- Activity 和 Fragment分离恰好适合用来实现MVP:Activity是创建和连接View与Presenter的总控制器
- 适配平板设备的布局或多视图屏幕的场景都可利用Fragment框架的优势
关键概念
该App(指官方TODO-MVP示例)中有四个功能:
- Tasks
- TaskDetail
- AddEditTask
- Statistics
每个功能拥有下列代码分工:
- 定义VIew和Presenter之间的“契约”接口
- 一个Activity类负责创建Fragment和Presenter
- 一个Fragment类实现VIew接口
- 一个Presenter类实现Presenter接口
一般来说,业务逻辑存在于Presenter中并依赖View完成Android中UI相关的工作。
View中几乎不包含逻辑:它将Presenter的命令转换为UI动作,并监听用户动作传递给Presenter。
“契约”接口用于定义View和Presenter之间的联系。
(译注:
有人立马就问到M哪去了,官方实例里M是轻的,与Repository和DataSource概念分离。在官方的另一个示例中有进一步的描述:http://www.cnblogs.com/x3d/p/6108998.html
/**
* Immutable model class for a Task.
*/
public final class Task {
@NonNull
private final String mId;
@Nullable
private final String mTitle;
@Nullable
private final String mDescription;
private final boolean mCompleted;
@NonNull
public String getId() {
return mId;
}
@Nullable
public String getTitle() {
return mTitle;
}
@Nullable
public String getTitleForList() {
if (!Strings.isNullOrEmpty(mTitle)) {
return mTitle;
} else {
return mDescription;
}
}
@Nullable
public String getDescription() {
return mDescription;
}
public boolean isCompleted() {
return mCompleted;
}
public boolean isActive() {
return !mCompleted;
}
public boolean isEmpty() {
return Strings.isNullOrEmpty(mTitle) &&
Strings.isNullOrEmpty(mDescription);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Task task = (Task) o;
return Objects.equal(mId, task.mId) &&
Objects.equal(mTitle, task.mTitle) &&
Objects.equal(mDescription, task.mDescription);
}
@Override
public int hashCode() {
return Objects.hashCode(mId, mTitle, mDescription);
}
@Override
public String toString() {
return "Task with title " + mTitle;
}
}
DataSource、Repository相关代码布局:

契约接口定义:
package com.example.android.architecture.blueprints.todoapp.taskdetail;
import com.example.android.architecture.blueprints.todoapp.BasePresenter;
import com.example.android.architecture.blueprints.todoapp.BaseView;
/**
* This specifies the contract between the view and the presenter.
*/
public interface TaskDetailContract {
interface View extends BaseView<Presenter> {
void setLoadingIndicator(boolean active);
void showMissingTask();
void hideTitle();
void showTitle(String title);
void hideDescription();
void showDescription(String description);
void showCompletionStatus(boolean complete);
void showEditTask(String taskId);
void showTaskDeleted();
void showTaskMarkedComplete();
void showTaskMarkedActive();
boolean isActive();
}
interface Presenter extends BasePresenter {
void editTask();
void deleteTask();
void completeTask();
void activateTask();
}
}
)
项目依赖
- Common Android support 库 (com.android.support.*)
- Android Testing Support 库 (Espresso, AndroidJUnitRunner…)
- Mockito
- Guava (null checking)
特性
复杂度 - 易理解性
使用架构性框架/库/工具类:
无
概念复杂度
低,基于Android的纯MVP实现。
可测试性
单元测试
高,Presenter可被单元测试,和仓库与数据源一样。
UI 测试
高,允许使用fake模块注入伪造(fake)数据进行测试。
代码对比
相比于不使用架构的传统项目,该示例引入了额外的类和接口:Presenter、Repositiy、契约接口等,所以MVP中代码行数更多一些。
| 语言 | 文件 | 空行 | 注释 | 代码 |
|---|---|---|---|---|
| Java | 46 | 1075 | 1451 | 3451 |
| XML | 34 | 97 | 337 | 601 |
| SUM | 80 | 1172 | 1788 | 4052 |
可维护性
简化功能的维护或新功能的迭代
高
学习成本
低
相关功能代码能容易查找定位、代码职责清晰。开发者无需熟悉任何外部的依赖就能对该项目开展工作。
Github项目地址:https://github.com/googlesamples/android-architecture/
[译]Google官方关于Android架构中MVP模式的示例的更多相关文章
- Google官方关于Android架构中MVP模式的示例续-DataBinding
基于前面的TODO示例,使用Data Binding库来显示数据并绑定UI元素的响应动作. 这个示例并未严格遵循 Model-View-ViewModel 或 Model-View-Presenter ...
- 浅谈Android架构之MVP,MVVM
概述 MVP(Model-View-Presenter)是传统MVC(Model-View-Controller)在Android开发上的一种变种.进化模式.主要用来隔离UI.UI逻辑和业务逻辑.数据 ...
- Android Studio重构之路,我们重新来了解一下Google官方的Android开发工具
Android Studio重构之路,我们重新来了解一下Google官方的Android开发工具 记得我的第一篇博客就是写Android Studio,但是现在看来还是有些粗糙了,所有重构了一下思路, ...
- 下载Google官方/CM Android源码自己主动又一次開始的Shell脚本
国内因为某种原因,下载CM或Google官方的Android源码总easy中断.总看着机器.一中断就又一次运行repo sync还太麻烦,所以我特意编写了一段shell脚本(download.sh). ...
- 如何结合整洁架构和MVP模式提升前端开发体验 - 整体架构篇
本文不详细介绍什么是整洁架构以及 MVP 模式,自行查看文章结尾相关链接文章. 整洁架构粗略介绍 下图为整洁架构最原始的结构图: Entities/Models:实体层,官方说法就是封装了企业里最通用 ...
- Android APP架构设计——MVP的使用示例
0. 前言 为了更好地进行移动端架构设计,我们最常用的就是MVC.MVP和MVVM,作为三个最耳熟能详的三大架构,应用可谓非常广泛.对于这三种架构设计以及优缺点已经在Android APP架构设计-- ...
- android中MVP模式(一) - 清风明月的专栏 - CSDN博客
presenter 主持人.主导器 ====== 1. 明确需求,界面如下:可存,可根据id读取数据. 包结构图 2. 建立bean public class UserBean { private S ...
- Android中MVP模式与MVC模式比較(含演示样例)
原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...
- Android应用中MVP开发模式
所谓MVP(Model-View-Presenter)模式.是将APP的结构分为三层: view - UI显示层 view 层主要负责: 提供UI交互 在presenter的控制下修改UI. 将业务事 ...
随机推荐
- 简析服务端通过GT导入SHP至PG的方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中需要在浏览器端直接上传SHP后服务端进行数据的自动入PG ...
- 免费高效实用的.NET操作Excel组件NPOI(.NET组件介绍之六)
很多的软件项目几乎都包含着对文档的操作,前面已经介绍过两款操作文档的组件,现在介绍一款文档操作的组件NPOI. NPOI可以生成没有安装在您的服务器上的Microsoft Office套件的Excel ...
- Python多线程爬虫爬取电影天堂资源
最近花些时间学习了一下Python,并写了一个多线程的爬虫程序来获取电影天堂上资源的迅雷下载地址,代码已经上传到GitHub上了,需要的同学可以自行下载.刚开始学习python希望可以获得宝贵的意见. ...
- Javascript高性能编程-提高Dom访问速度
在浏览器中对于Dom的操作和普通的脚本的操作处于两个不同的dll中,两个dll的交互是比较耗时的,优化对Dom的操作可以提高脚本的执行速度.下面是对如何优化的一些总结: 将需要多次操作的节点存储在一个 ...
- arcgis api for js入门开发系列四地图查询(含源代码)
备注:由于实现本篇功能的需求,修改了地图数据的dlsearch.mxd,然后更新了地图服务,需要的在文章最后有提供最新的mxd以及源代码下载的 上一篇实现了demo的地图工具栏,本篇新增地图查询功能, ...
- java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE
Android发出HTTP请求时出现了这个错误: java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INST ...
- Java 进阶 hello world! - 中级程序员之路
Java 进阶 hello world! - 中级程序员之路 Java是一种跨平台的语言,号称:"一次编写,到处运行",在世界编程语言排行榜中稳居第二名(TIOBE index). ...
- jetBrain系列软件
请尽量支持正版软件!https://www.jetbrains.com/ 本文仅供参考 以下提供一种方法可以无限期体验JetBrain2016系列软件. 1.下载JetbrainsCrack-2.5. ...
- Topshelf 学习 跨平台
Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主. 官网:http://topshelf-project.com Git ...
- DTO – 服务实现中的核心数据
在一个Web服务的实现中,我们常常需要访问数据库,并将从数据库中所取得的数据显示在用户页面中.这样做的一个问题是:用于在用户页面上展示的数据和从数据库中取得的数据常常具有较大区别.在这种情况下,我们常 ...