详解Android中的MVP架构分解和实现

1、概述

传统的Android开发架构一般是MVC模式,

  • Model:业务逻辑和实体模型
  • View:对应于布局文件
  • Controllor:对应于Activity

单独从逻辑看起来非常好,与我们做Web开发时,开发模式类似,但在实际开发中,View对应于布局文件,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,Activity既像View又像Controller(MVVP架构中包括数据绑定),导致Activity中职责太重,耦合度大。修改和维护起来非常麻烦。

2、MVP介绍

MVP架构中,View 对应于Activity,负责View的绘制以及与用户交互

Model 依然是业务逻辑和实体模型,Presenter 负责完成View于Model间的交互。

(1)Model层

模型层之中做的工作是具体业务逻辑处理的实现,都伴随着程序中各种数据的处理,复杂一些的就需要实现一个Interface来松耦合了。

(2)View层

视图层体现的很轻薄,负责显示数据、提供友好界面跟用户交互就行。MVP下Activity和Fragment体现在了这一 层,Activity一般也就做加载UI视图、设置监听再交由Presenter处理的一些工作,所以也就需要持有相应Presenter的引用。处理一些基本UI逻辑,判断是否为空。

(3)Presenter层

Presenter这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做具体的业务操作。

MVP架构和MVC架构区别:

MVC中是允许Model和View进行交互的,而MVP中,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的。

3、MVP实现

百说不如一做。实现一个简单的登录操作。

项目结构如下:

(1)Model层实现

首先实现User实体类:

package com.chunsoft.blogcontent.bean;

/**
 * Developer:chunsoft on 2017/2/7 11:19
 * Content:实体类
 */

public class User {

 private String username;
 private String password;

 public String getUsername() {
  return username;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public String getPassword() {
  return password;
 }

 public void setPassword(String password) {
  this.password = password;
 }
}

model层主要实现业务逻辑处理,在本文案例中,主要逻辑处理就是登录,抽取了一个接口和一个实现类,在login操作,模拟登录操作,Thread.sleep()模拟耗时,由于是耗时操作,通过一个回调接口通知登录状态。

model层接口:

package com.chunsoft.blogcontent.model;

import com.chunsoft.blogcontent.RequestCallback;
import com.chunsoft.blogcontent.bean.User;

/**
 * Developer:chunsoft on 2017/2/7 11:30
 * Email:chun_soft@qq.com
 * Content:Model层主要处理业务方法和实体模型
 */

public interface LoginModel {
 void login(String username, String password, RequestCallback<User> callback);
}

model层接口实现:

package com.chunsoft.blogcontent.model.impl;

import com.chunsoft.blogcontent.RequestCallback;
import com.chunsoft.blogcontent.bean.User;
import com.chunsoft.blogcontent.model.LoginModel;

/**
 * Developer:chunsoft on 2017/2/7 11:31
 * Content:Model层的实现
 */

public class LoginModelImpl implements LoginModel{
 @Override
 public void login(final String username, final String password, final RequestCallback<User> callback) {
  //模仿登录操作
  new Thread() {
   @Override
   public void run() {
    try {
     Thread.sleep(2*1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    if ("chunsoft".equals(username) && "123456".equals(password)) {
     User user = new User();
     user.setUsername(username);
     user.setPassword(password);
     callback.onSuccess(user);
    } else {
     callback.onFailure("登录失败");
    }
   }
  }.start();
 }
}

回调接口:

package com.chunsoft.blogcontent;

/**
 * Developer:chunsoft on 2017/2/7 11:35
 * Content:回调接口
 */

public interface RequestCallback<T> {
 void onSuccess(T datas);
 void onFailure(String msg);
}

(2)View层实现

对于View层接口定义,首先考虑功能上的操作,然后考虑:

  • 该操作需要什么?(getUserName等)
  • 该操作的结果,对应的反馈?(toMainActivity等)
  • 该操作过程中交互友好?( showLoading)

view层接口:

package com.chunsoft.blogcontent.view;

import com.chunsoft.blogcontent.bean.User;

/**
 * Developer:chunsoft on 2017/2/7 11:54
 * Email:chun_soft@qq.com
 * Content:view层接口
 */

public interface LoginView {
 String getUserName();
 String getPassword();

 void showLoading();
 void hideLoading();

 void toMainActvity(User user);
 void showFailedError(String msg);
}

view层实现,其实就是Activity,可以看到Activity的代码量大大减少,且逻辑清晰:

package com.chunsoft.blogcontent;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.chunsoft.blogcontent.bean.User;
import com.chunsoft.blogcontent.presenter.impl.LoginPresenterImpl;
import com.chunsoft.blogcontent.view.LoginView;

public class MainActivity extends AppCompatActivity implements LoginView{

 private EditText et_mobile,et_password;
 private ProgressBar pb;
 private Button btn_login;

 private LoginPresenterImpl mLoginPresenter = new LoginPresenterImpl(this);

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  et_mobile = (EditText) findViewById(R.id.et_mobile);
  et_password = (EditText) findViewById(R.id.et_password);
  pb = (ProgressBar) findViewById(R.id.pb);
  btn_login = (Button) findViewById(R.id.btn_login);

  btn_login.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    mLoginPresenter.login();
   }
  });
 }

 @Override
 public String getUserName() {
  return et_mobile.getText().toString();
 }

 @Override
 public String getPassword() {
  return et_password.getText().toString();
 }

 @Override
 public void showLoading() {
  pb.setVisibility(View.VISIBLE);
 }

 @Override
 public void hideLoading() {
  pb.setVisibility(View.INVISIBLE);
 }

 @Override
 public void toMainActvity(User user) {
  Toast.makeText(this,user.getUsername() + "登录成功",Toast.LENGTH_SHORT).show();
 }

 @Override
 public void showFailedError(String msg) {
  Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
 }
}

(3)Presenter层实现

Presenter层是Model层和View层的桥梁,本文中依然抽象出一个接口和一个实现类,定义时主要看该功能有什么操作,例如,登录:

Presenter接口:

package com.chunsoft.blogcontent.presenter;

/**
 * Developer:chunsoft on 2017/2/7 11:49
 * Content:Presenter层接口
 */
public interface LoginPresenter {
  void login();
}

Presenter层实现:

package com.chunsoft.blogcontent.presenter.impl;

import android.os.Handler;

import com.chunsoft.blogcontent.RequestCallback;
import com.chunsoft.blogcontent.bean.User;
import com.chunsoft.blogcontent.model.LoginModel;
import com.chunsoft.blogcontent.model.impl.LoginModelImpl;
import com.chunsoft.blogcontent.presenter.LoginPresenter;
import com.chunsoft.blogcontent.view.LoginView;

/**
 * Developer:chunsoft on 2017/2/7 11:50
 * Content:Presenter层实现
 */

public class LoginPresenterImpl implements LoginPresenter {

 private LoginView loginView;
 private LoginModel loginModel;

 private Handler mHandler = new Handler();

 //在构造函数中初始化
 public LoginPresenterImpl(LoginView loginView) {
  this.loginModel = new LoginModelImpl();
  this.loginView = loginView;
 }

 @Override
 public void login() {
  loginView.showLoading();
  loginModel.login(loginView.getUserName(), loginView.getPassword(), new RequestCallback<User>() {
   @Override
   public void onSuccess(final User datas) {
    //登录成功
    mHandler.post(new Runnable() {
     @Override
     public void run() {
      loginView.toMainActvity(datas);
      loginView.hideLoading();
     }
    });
   }

   @Override
   public void onFailure(final String msg) {
    //登录失败
    mHandler.post(new Runnable() {
     @Override
     public void run() {
      loginView.showFailedError(msg);
      loginView.hideLoading();
     }
    });
   }
  });
 }
}

Presenter层是Model层和View层的桥梁,Model层和View层不直接通信,所以Presenter层需要Model层和View层的实现类,从View层中获取重要参数,交给Model 层调用业务逻辑处理,执行后的结果和反馈再交给View层去展示。

本文源码下载

本文是简单的用MVP架构实现登录操作,而目前主流开发,将Rxjava、Retrofit和MVP结合进行开发,逻辑更加清晰,下篇文章将详细介绍这部分实现。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android如何从实现到封装一个MVP详解

    前言 MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示.下面这篇文章主要给大家介绍了关于Android从实现到封装MVP的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. MVP之间的联系 大概简单的解释就是M->module处理数据,V->Act显示界面,P->M和V沟通的渠道,即P用来将数据和界面联系到一起,这样子界面和数据就可以完全独立开来,Ac

  • Android MVP模式实战教程

    一.什么是MVP 在网上找了些资料,整理如下: MVP是模型(Model).视图(View).主持人(Presenter)的缩写,分别代表项目中3个不同的模块. 模型(Model):负责处理数据的加载或者存储,比如从网络或本地数据库获取数据等: 视图(View):负责界面数据的展示,与用户进行交互: 主持人(Presenter):相当于协调者,是模型与视图之间的桥梁,将模型与视图分离开来. 如下图所示,View与Model并不直接交互,而是使用Presenter作为View与Model之间的桥梁

  • Android MVP模式ListView中嵌入checkBox的使用方法

    MVP模式 ListView中嵌入checkBox的使用 本文写的是一个小demo,如何在ListView中嵌入checkBox配合使用,本篇文章与前面的嵌入Button类似,同样的采用MVP模式的写代码,本次案例中会有几个小细节,我将会在案例中介绍. 程序基本框架如下: View层: MainActivity.java public class MainActivity extends AppCompatActivity implements ViewInter<MyBean>{ //Lis

  • Android中mvp模式使用实例详解

    MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示.作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller. 在MVC里,View是可以直接访问

  • 详解Android MVP开发模式

    本文主要讲解MVP开发模式以及具体实例. 一.简介 MVP(Model View Presenter)模式是著名的MVC(Model View Controller)模式的一个演化版本,目前它在Android应用开发中越来越重要了.初看起来我们会感觉增加了很多类接口代码看起来更加清晰. MVP模式可以分离显示层和逻辑层,所以功能接口如何工作与功能的展示可以实现分离,MVP模式理想化地可以实现同一份逻辑代码搭配不同的显示界面.不过MVP不是一个结构化的模式,它只是负责显示层而已,任何时候都可以在自

  • 完整的Android MVP开发之旅

    开发背景 最近是在做一个与健身相关的APP,里面有训练器模块基本功能是按照特点动作的演示和描述来引导用户完成训练.在第一个版本时由于没接触过些类项目与功能花了几周的时间大概1500行代码才完成这个功能, 当时虽然我已经尽量让代码表现的清晰,但是可以想像到当一个Activity中包含这么多代码是什么感觉.自己维护起来都难受. 先谈设计 有了前一次设计经验此次开发使用MVP.模块化.面向接口等概念,将整个训练器分为控制器.数据模型.音频.视图.可训练对象五个模块分别用以下接口表示: ITrainer

  • Android开发:浅谈MVP模式应用与内存泄漏问题解决

    最近博主开始在项目中实践MVP模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解MVP架构. MVP简介 M-Modle,数据,逻辑操作层,数据获取,数据持久化保存.比如网络操作,数据库操作 V-View,界面展示层,Android中的具体体现为Activity,Fragment P-Presenter,中介者,连接Modle,View层,同时持有modle引用和view接口引用 示例代码 Modle层操作 public class TestModle

  • 浅谈Android官方MVP架构解读

    综述 对于MVP (Model View Presenter)架构是从著名的MVC(Model View Controller)架构演变而来的.而对于Android应用的开发中本身可视为一种MVC架构.通常在开发中将XML文件视为MVC中的View角色,而将Activity则视为MVC中的Controller角色.不过更多情况下在实际应用开发中Activity不能够完全充当Controller,而是Controller和View的合体.于是Activity既要负责视图的显示,又要负责对业务逻辑的

  • 详解MVP模式在Android开发中的应用

    一.MVP介绍  随着UI创建技术的功能日益增强,UI层也履行着越来越多的职责.为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生. 在MVP模式里通常包含4个要素: (1)View:负责绘制UI元素.与用户进行交互(在Android中体现为Activity); (2)View interface:需要View实现的接口,Vie

  • 详解Android中的MVP架构分解和实现

    1.概述 传统的Android开发架构一般是MVC模式, Model:业务逻辑和实体模型 View:对应于布局文件 Controllor:对应于Activity 单独从逻辑看起来非常好,与我们做Web开发时,开发模式类似,但在实际开发中,View对应于布局文件,实际上关于该布局文件中的数据绑定的操作,事件处理的代码都在Activity中,Activity既像View又像Controller(MVVP架构中包括数据绑定),导致Activity中职责太重,耦合度大.修改和维护起来非常麻烦. 2.MV

  • 详解Android中Intent对象与Intent Filter过滤匹配过程

    如果对Intent不是特别了解,可以参见博文<详解Android中Intent的使用方法>,该文对本文要使用的action.category以及data都进行了详细介绍.如果想了解在开发中常见Intent的使用,可以参见<Android中Intent习惯用法>. 本文内容有点长,希望大家可以耐心读完. 本文在描述组件在manifest中注册的Intent Filter过滤器时,统一用intent-filter表示. 一.概述 我们知道,Intent是分两种的:显式Intent和隐式

  • 详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题

    详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题 今天在项目中实现了一个效果,主要是画一个圆.为了后续使用方便,将这个圆封装在一个自定义Actor(CircleActot)中,后续想显示一个圆的时候,只要创建一个CircleActor中即可. 部分代码如下所示: package com.ef.smallstar.unitmap.widget; import android.content.res.Resources; import

  • 详解Android中图片的三级缓存及实例

    详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

  • 详解Android中的Service

    Service简介: Service是被设计用来在后台执行一些需要长时间运行的操作. Android由于允许Service在后台运行,甚至在结束Activity后,因此相对来说,Service相比Activity拥有更高的优先级. 创建Service: 要创建一个最基本的Service,需要完成以下工作:1)创建一个Java类,并让其继承Service 2)重写onCreate()和onBind()方法 其中,onCreate()方法是当该Service被创建时执行的方法,onBind()是该S

  • 详解Android中Handler的内部实现原理

    本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文<详解Android中Handler的使用方法>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功

  • 详解Android 中AsyncTask 的使用

    详解Android 中AsyncTask 的使用 1.首先我们来看看AsyncTask 的介绍:   Handler 和 AsyncTask 都是android 中用来实现异步任务处理的方式:其中: Handler 实例向 UI 线程发送消息,完成界面更新, 优点:对整个过程控制的比较精细:         缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制: AsyncTask :比Handler 更轻量级一些,适用于简单的异步处理: 优点:简单 | 快捷 | 过程可控:    

  • 详解Android中获取软键盘状态和软键盘高度

    详解Android中获取软键盘状态和软键盘高度 应用场景 在Android应用中有时会需要获取软键盘的状态(即软键盘是显示还是隐藏)和软键盘的高度.这里列举了一些可能的应用场景. 场景一 当软键盘显示时,按下返回键应当是收起软键盘,而不是回退到上一个界面,但部分机型在返回键处理上有bug,按下返回键后,虽然软键盘会自动收起,但不会消费返回事件,导致Activity还会收到这次返回事件,执行回退操作,这时就需要判断,如果软键盘刚刚由显示变为隐藏状态,就不执行回退操作. 场景二 当软键盘弹出后,会将

  • 详解Android中fragment和viewpager的那点事儿

    在之前的博文<Android 中使用 ViewPager实现屏幕页面切换和页面轮播效果>和<详解Android中Fragment的两种创建方式>以及<Android中fragment与activity之间的交互(两种实现方式)>中我们介绍了ViewPager以及Fragment各自的使用场景以及不同的实现方式. 那如果将他们两结合起来,会不会擦出点火花呢,答案是肯定的.之前在介绍ViewPager时,我们实现了多个ImageView的切换,并配合更新导航原点的状态.那我

  • 详解Android中PopupWindow在7.0后适配的解决

    本文介绍了详解Android中PopupWindow在7.0后适配的解决,分享给大家,具体如下: 这里主要记录一次踩坑的经历. 需求:如上图左侧效果,想在按钮的下方弹一个PopupWindow.嗯,很简单一个效果,然当适配7.0后发现这个PopupWindow显示异常,然后网上找到了下面这种方案. 7.0适配方案(但7.1又复现了) // 将popupWindow显示在anchor下方 public void showAsDropDown(PopupWindow popupWindow, Vie

随机推荐