android mvp

In this tutorial, we’ll be discussing the android MVP principles and develop an application based on it. Since the start, we’ve been developing applications by adding all the business logic inside the Activity. Let’s analyze the cons of our current approach before digging into the new principles.

在本教程中,我们将讨论android MVP原理,并基于此原理开发应用程序。 从一开始,我们就通过在Activity中添加所有业务逻辑来开发应用程序。 在深入探讨新原理之前,让我们分析一下当前方法的弊端。

Android MVP (Android MVP)

With our current approach, the MainActivity class contains all the implementation logic of our application. We’ve been using stuff ranging from Retrofit callbacks to data models(SharedPref, POJO classes) all inside the Activity class.

使用我们当前的方法,MainActivity类包含我们应用程序的所有实现逻辑。 我们一直在Activity类中使用从Retrofit回调到数据模型(SharedPref,POJO类)的内容。

Eventually, our Activities become god classes and cause problems in maintainability, readability, scalability and refactoring an already bloated code.

最终,我们的活动成为了上帝的职业,并在可维护性,可读性,可伸缩性和重构已经肿的代码方面引起了问题。

Unit testing gets tough since the implementation logic is tightly coupled with the Android APIs. This is where MVP ( Model View Presenter) comes in handy. It allows us to write a clean and flexible code base while giving the luxury to switch any part of the code without much hassle.

由于实现逻辑与Android API紧密结合,因此单元测试变得越来越困难。 这是MVP(模型视图演示器)派上用场的地方。 它使我们能够编写简洁,灵活的代码库,同时又可以轻松切换代码的​​任何部分,而无须麻烦。

模型视图演示者 (Model View Presenter)

Model View Presenter divides our application into three layers namely the Model, View and Presenter.

Model View Presenter将我们的应用程序分为三层,即Model,View和Presenter。

  1. Model: This handles the data part of our application模型 :处理我们应用程序的数据部分
  2. Presenter: It acts as a bridge that connects a Model and a View.演示者 :它充当连接模型和视图的桥梁。
  3. View: This is responsible for laying out views with the relevant data as instructed by the Presenter视图 :这负责按照演示者的指示使用相关数据布置视图

Note: The View never communicates with Model directly.

注意 :View从不直接与Model通信。

Android MVP架构 (Android MVP Architecture)

The diagram below depicts a basic MVP structure.

下图描述了基本的MVP结构。

Android MVP准则 (Android MVP Guidelines)

  1. Activity, Fragment and a CustomView act as the View part of the application.Activity,Fragment和CustomView充当应用程序的View部分。
  2. The Presenter is responsible for listening to user interactions (on the View) and model updates (database, APIs) as well as updating the Model and the View.演示者负责侦听用户交互(在View上)和模型更新(数据库,API),以及更新Model和View。
  3. Generally, a View and Presenter are in a one to one relationship. One Presenter class manages one View at a time.通常,视图和演示者之间是一对一的关系。 一个Presenter类一次管理一个View。
  4. Interfaces need to be defined and implemented to communicate between View-Presenter and Presenter-Model.需要定义和实现接口以在View-Presenter和Presenter-Model之间进行通信。
  5. The Presenter is responsible for handling all the background tasks. Android SDK classes must be avoided in the presenter classes.演示者负责处理所有后台任务。 在presenter类中必须避免使用Android SDK类。
  6. The View and Model classes can’t have a reference of one another.View和Model类不能互相引用。

Having covered the theory of MVP architecture, let’s build an android MVP app now.

涵盖了MVP体系结构的理论之后,让我们现在构建一个android MVP应用程序。

Android MVP示例应用程序项目结构 (Android MVP Example App Project Structure)

The android mvp project consists of 3 interface files (also known as contracts). The Impl files are where the interfaces are implemented.

android mvp项目包含3个接口文件(也称为合同)。 Impl文件是实现接口的位置。

We’ll be creating a single activity application that’ll display a random quote from a list of quotes present in an ArrayList. We’ll see how the presenter manages to keep the business logic of the application away from the activity class.

我们将创建一个活动应用程序,该应用程序将显示ArrayList中存在的引号列表中的随机引号。 我们将看到演示者如何管理使应用程序的业务逻辑远离活动类。

Note: Interactors are classes built for fetching data from your database, web services, or any other data source.

注意: Interactor是为从数据库,Web服务或任何其他数据源中获取数据而构建的类。

Android MVP应用程式程式码 (Android MVP app code)

The code for the activity_main.xml layout is given below.

下面给出了activity_main.xml布局的代码。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.journaldev.hellomvp.MainActivity"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:text="Implementing MVP Pattern in this Application."app:layout_constraintBottom_toBottomOf="parent"android:padding="8dp"android:gravity="center"android:textAppearance="?android:attr/textAppearanceSearchResultTitle"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:id="@+id/textView" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="GET NEXT QUOTE"android:layout_margin="@android:dimen/notification_large_icon_height"app:layout_constraintTop_toBottomOf="@+id/textView"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent" /><ProgressBarandroid:id="@+id/progressBar"style="?android:attr/progressBarStyleLarge"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:visibility="gone"app:layout_constraintBottom_toBottomOf="parent"/></android.support.constraint.ConstraintLayout>

The code for the GetQuoteInteractor interface is given below.

下面给出了GetQuoteInteractor接口的代码。

package com.journaldev.hellomvp;public interface GetQuoteInteractor {interface OnFinishedListener {void onFinished(String string);}void getNextQuote(OnFinishedListener listener);
}

It contains a nested interface onFinishedListener. We’ll be using a handler inside our GetQuoteInteractorImpl.java below. On completion of the handler, the above onFinished method would be triggered.

它包含一个嵌套接口onFinishedListener。 我们将在下面的GetQuoteInteractorImpl.java中使用处理程序。 处理程序完成后,将触发上述onFinished方法。

package com.journaldev.hellomvp;import android.os.Handler;import java.util.Arrays;
import java.util.List;
import java.util.Random;public class GetQuoteInteractorImpl implements GetQuoteInteractor {private List<String> arrayList = Arrays.asList("Be yourself. everyone else is already taken.","A room without books is like a body without a soul.","You only live once, but if you do it right, once is enough.","Be the change that you wish to see in the world.","If you tell the truth, you don't have to remember anything.");@Overridepublic void getNextQuote(final OnFinishedListener listener) {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {listener.onFinished(getRandomString());}}, 1200);}private String getRandomString() {Random random = new Random();int index = random.nextInt(arrayList.size());return arrayList.get(index);}
}

The MainView.java interface is defined below.

MainView.java接口在下面定义。

package com.journaldev.hellomvp;public interface MainView {void showProgress();void hideProgress();void setQuote(String string);
}

showProgress() and hideProgress() would be used for displaying and hiding the progressBar while the next random quote is fetched from the GetQuoteInteractorImpl class.

当从GetQuoteInteractorImpl类获取下一个随机报价时,将使用showProgress()hideProgress()来显示和隐藏progressBar 。

setQuote() will set the random string on the textView.

setQuote()将在setQuote()设置随机字符串。

The code for the MainPresenter.java interface is given below.

MainPresenter.java接口的代码如下。

package com.journaldev.hellomvp;public interface MainPresenter {void onButtonClick();void onDestroy();
}

The MainPresenterImpl.java class is defined below.

MainPresenterImpl.java类在下面定义。

package com.journaldev.hellomvp;public class MainPresenterImpl implements MainPresenter, GetQuoteInteractor.OnFinishedListener {private MainView mainView;private GetQuoteInteractor getQuoteInteractor;public MainPresenterImpl(MainView mainView, GetQuoteInteractor getQuoteInteractor) {this.mainView = mainView;this.getQuoteInteractor = getQuoteInteractor;}@Overridepublic void onButtonClick() {if (mainView != null) {mainView.showProgress();}getQuoteInteractor.getNextQuote(this);}@Overridepublic void onDestroy() {mainView = null;}@Overridepublic void onFinished(String string) {if (mainView != null) {mainView.setQuote(string);mainView.hideProgress();}}
}

The above class implements the Presenter and nested interface from GetQuoteInteractor. Moreover it instantiates the MainView and GetQuoteInteractor interfaces (View and Model respectively).

上面的类实现了GetQuoteInteractor的Presenter和嵌套接口。 此外,它实例化MainViewGetQuoteInteractor接口(分别为View和Model)。

onButtonClick method would be triggered in the MainActivity class when the button is clicked and will display a progressBar while it gets the next random quote.

单击按钮时,将在MainActivity类中触发onButtonClick方法,并在获取下一个随机引用时显示progressBar

onDestroy() method would be invoked inside the lifecycle method onDestroy() of the MainActivity.

onDestroy()方法将在MainActivity的生命周期方法onDestroy()中调用。

onFinished() method gets called when the handler is completed inside the GetQuoteInteractorImpl. It returns the string which will be displayed in the TextView using the MainView’s instance.

当处理程序在GetQuoteInteractorImpl中完成时,将调用onFinished()方法。 它返回将使用MainView的实例显示在TextView中的字符串。

The code for the MainActivity.java which implements MainView interface is given below.

下面给出了实现MainView接口的MainActivity.java代码。

package com.journaldev.hellomvp;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;import static android.view.View.GONE;public class MainActivity extends AppCompatActivity implements MainView {private TextView textView;private Button button;private ProgressBar progressBar;MainPresenter presenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = (TextView) findViewById(R.id.textView);button = (Button) findViewById(R.id.button);progressBar = (ProgressBar) findViewById(R.id.progressBar);presenter = new MainPresenterImpl(this, new GetQuoteInteractorImpl());button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {presenter.onButtonClick();}});}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onDestroy() {super.onDestroy();presenter.onDestroy();}@Overridepublic void showProgress() {progressBar.setVisibility(View.VISIBLE);textView.setVisibility(View.INVISIBLE);}@Overridepublic void hideProgress() {progressBar.setVisibility(GONE);textView.setVisibility(View.VISIBLE);}@Overridepublic void setQuote(String string) {textView.setText(string);}
}

showProgress() and hideProgress() methods shows and hides the textView as well to prevent overlapping the current text and the progressBar.

showProgress()hideProgress()方法还显示和隐藏hideProgress() ,以防止当前文本和progressBar重叠。

Note: The above class contains is now devoid of the business logic and is responsible for only updating the UI based on the changes triggered by the Presenter layer.

注意:上面的类包含的内容现在没有业务逻辑,仅负责根据Presenter层触发的更改来更新UI。

The output of the above android MVP application is given below.

上面的android MVP应用程序的输出如下。

Note: Google recommends to keep a single contract interface file for the Model View and Presenter.

注意:Google建议为Model View and Presenter保留一个合同界面文件。

So let’s club the interfaces defined above into one.

因此,让我们将上面定义的接口合并为一个。

The project structure now looks like this:

现在,项目结构如下所示:

The code for the MainContract.java interface is given below.

MainContract.java接口的代码如下。

package com.journaldev.hellomvp;public interface MainContract {interface MainView {void showProgress();void hideProgress();void setQuote(String string);}interface GetQuoteInteractor {interface OnFinishedListener {void onFinished(String string);}void getNextQuote(OnFinishedListener onFinishedListener);}interface Presenter {void onButtonClick();void onDestroy();}
}

This brings an end to this tutorial. There’s a lot more to explore in MVP pattern that we’ll be discussing soon.

本教程到此结束。 关于MVP模式,还有很多要探讨的内容,我们将很快讨论。

You can download the Android MVP Hello World Project from the link below.

您可以从下面的链接下载Android MVP Hello World项目

Download Android MVP Hello World Project下载Android MVP Hello World项目

Reference: Wikipedia

参考: 维基百科

翻译自: https://www.journaldev.com/14886/android-mvp

android mvp

android mvp_Android MVP相关推荐

  1. java mvp模式_什么是mvp开发模式?(下面就对Android中MVP做一些阐述)

    MVP作为一种MVC的演化版本在Android开发中受到了越来越多的关注.值得注意的是,MVP不像JavaEE有着SSH这三个成熟框架支持推动着,所以在运用MVP时一定要做好自己的理解,并且尽量预知自 ...

  2. Android之MVP模式

    今天来看看Android的MVP模式,使用框架开发,开发速度以及代码的目录结构会别有一番风格. Google的demo:https://github.com/googlesamples/android ...

  3. Android的MVP设计架构:网络加载图片为例

    再写一个Android中MVP的实例,该例子通过okhttp加载一张网络图片到ImageView,使用MVP设计架构实现. 架构的抽象建模: package zhangphil.pattern;/** ...

  4. android基于MVP小说网络爬虫、宝贝社区APP、仿虎扑钉钉应用、滑动阴影效果等源码...

    Android精选源码 android宝贝社区app源码 android仿Tinder最漂亮的一个滑动效果 android仿滴滴打车开具页,ListView粘性Header Android基于MVP模 ...

  5. android基于MVP小说网络爬虫、宝贝社区APP、仿虎扑钉钉应用、滑动阴影效果等源码

    Android精选源码 android宝贝社区app源码 android仿Tinder最漂亮的一个滑动效果 android仿滴滴打车开具发票页,ListView粘性Header Android基于MV ...

  6. android项目集成okgo,Android中MVP+RXJAVA+OKGO框架

    [实例简介] Android中MVP+RXJAVA+OKGO框架 Glide的封装 沉浸式状态栏 butterknife 和recyclerview的使用 [实例截图] [核心代码] 882096ee ...

  7. android搭建网络框架,Android 搭建MVP+Retrofit+RxJava网络请求框架(三)

    上一篇中主要是将mvp+rxjava+retrofit进行了结合,本篇主要是对mvp框架的优化:建议先去看上一篇:Android 搭建MVP+Retrofit+RxJava网络请求框架(二) 针对vi ...

  8. 解读Android官方MVP项目单元测试

    Google在3月份推出了一个项目,用来介绍Android MVP架构的各种组合,可以认为是官方在这方面的最佳实践.令人称道的是除了MVP本身之外,这些工程配备了极其完善的单元测试用例,学习价值极高. ...

  9. android采用MVP完整漫画APP、钉钉地图效果、功能完善的音乐播放器、仿QQ动态登录效果、触手app主页等源码...

    Android精选源码 一个可以上拉下滑的Ui效果,觉得好看可以学学 APP登陆页面适配 一款采用MVP的的完整漫画APP源码 android实现钉钉地图效果源码 一个使用单个文字生成壁纸图片的app ...

最新文章

  1. 总体设计和登陆服务器 [游戏服务器的设计思路 转]
  2. 循环求100内质数 php_C8循环
  3. python开发的优秀界面-八款常用的 Python GUI 开发框架推荐
  4. 谢百三:房价上涨的九大原因
  5. com.fasterxml.jackson.databind.JsonMappingException: Multiple back-reference properties with name ‘d
  6. [pytorch、学习] - 5.9 含并行连结的网络(GoogLeNet)
  7. 非网络引用element-ui css导致图标无法正常显示的解决办法
  8. linux下wget的用法
  9. window环境读linux文件,Windows本地环境和Linux腾讯云服务器之间传输文件的方法
  10. 深度学习入门笔记:Day-10
  11. 异常检测: 多元高斯分布
  12. AIDA64 5.92.4300 序列号
  13. 微信小程序 选项卡设置
  14. 【TA-霜狼_may-《百人计划》】图形3.3 曲面细分与几何着色器 大规模草渲染
  15. GprMax2D ——ABC(吸收边界条件)相关命令
  16. 2.10 分块矩阵求逆
  17. 读《潜伏在办公室》第二季
  18. Neuron:自动优化TMS线圈放置,实现个性化靶向功能网络刺激
  19. 观《哪吒之魔童降世》有感
  20. Atari 2600 新书:主机游戏的一次黎明冒险

热门文章

  1. [转载] 七龙珠第一部——第005话 邪恶沙漠的雅木茶
  2. Delphi调用外部程序详解
  3. 程序设计基础(C语言)教学案例-序言
  4. [转载] python--isalnum()函数
  5. [转载] 快速入门(完整):Python实例100个(基于最新Python3.7版本)
  6. 通过宝塔webhook,实现git自动拉取服务器代码
  7. [Tool] SourceTree初始化GitFlow遇到错误(git command not found)的解决方案
  8. Java基础之IO流
  9. MVVM模式下 触发器多条件判断
  10. PostgreSQL的 initdb 源代码分析之十六