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

作者:chun_soft 时间:2022-11-30 08:06:29 

1、概述

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

  • Model:业务逻辑和实体模型

  • View:对应于布局文件

  • Controllor:对应于Activity

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

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

2、MVP介绍

详解Android中的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架构区别:

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

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

3、MVP实现

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

项目结构如下:

详解Android中的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结合进行开发,逻辑更加清晰,下篇文章将详细介绍这部分实现。

来源:http://blog.csdn.net/ztchun/article/details/54894516

标签:android,mvp
0
投稿

猜你喜欢

  • 推荐史上最全的IDEA好用插件

    2023-02-22 21:35:04
  • IDEA 2021.1 的 Win 和 Mac 快捷键大全

    2023-02-27 13:01:28
  • Java中List.of()和Arrays.asList()的区别及原因分析

    2023-08-06 00:33:16
  • Java设计模式之观察者模式_动力节点Java学院整理

    2022-01-14 12:27:47
  • 详解C#多线程编程之进程与线程

    2021-07-18 14:15:36
  • MyEclipse2017创建Spring项目的方法

    2023-01-02 17:00:25
  • Java中String的JdbcTemplate连接SQLServer数据库的方法

    2022-09-05 00:34:12
  • Android jni调试打印char阵列的实例详解

    2022-06-18 14:55:40
  • java中初始化MediaRecorder的实现方法

    2023-11-29 03:54:52
  • 解析mybatis-plus中的resultMap简单使用

    2021-09-03 03:53:06
  • java实现马踏棋盘的算法

    2023-11-29 17:00:29
  • flutter实现发送验证码功能

    2023-07-05 19:03:12
  • java统计文件中每个字符出现的个数

    2021-12-22 06:43:42
  • Mybatis RowBounds 限制查询条数的实现代码

    2022-11-18 17:26:03
  • C#中字符串的加密的源码

    2023-09-14 22:35:34
  • C#中可枚举类型详解

    2023-03-24 20:39:15
  • C#实现JWT无状态验证的实战应用解析

    2022-07-28 09:20:26
  • android 触屏的震动响应接口调用方法

    2021-08-04 08:33:34
  • 新闻列表的分页查询java代码实现

    2022-02-24 19:46:25
  • Android 判断某个Activity 是否在前台运行的实例

    2023-07-24 19:29:21
  • asp之家 软件编程 m.aspxhome.com