如何使用MVP架构Android应用项目

目录

  1. MVP简介
  2. MVP结构
  3. MVP与MVC区别
  4. 实战演习

正文

1、MVP简介

相信大家对MVC都是比较熟悉了:M-Model-模型、V-View-视图、C-Controller-控制器,MVP作为MVC的演化版本,那么类似的MVP所对应的意义:M-Model-模型、V-View-视图、P-Presenter-表示器。从MVC和MVP两者结合来看,Controlller/Presenter在MVC/MVP中都起着逻辑控制处理的角色,起着控制各业务流程的作用。而MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控View与Model之间的间接交互,MVP的结构图如下所示,对于这个图理解即可而不必限于其中的条条框框,毕竟在不同的场景下多少会有些出入的。在Android中很重要的一点就是对UI的操作基本上需要异步进行也就是在MainThread中才能操作UI,所以对View与Model的切断分离是合理的。此外Presenter与View、Model的交互使用接口定义交互操作可以进一步达到松耦合也可以通过接口更加方便地进行单元测试。 

(引用该文章:http://zhengxiaopeng.com/2015/02/06/Android中的MVP/)

2、MVP结构

View View通常来说就是有Activity、Fragment实现的,View会包含一个或多个Presenter的引用来满足视图的业务逻辑。View和Presenter的交互是双向的,即View层可以调用Presenter的逻辑方法,Presenter也可以控制View的显示。 Presenter Presenter作为Model和View的桥梁,负责从Model拿到数据进行处理并返回给View。但Presenter和其他两层的沟通是通过接口协议进行的,所以每个Presenter中通常会包涵一个或多个接口协议。
Model 和MVC一样,作为数据仓库只负责对APP数据进行处理。 Android开发MVP模式实践中的示例将APP分为以下四层。

Entities:APP中的业务类。 Use Cases:负责从将Entities中的数据进行处理和包装。 Presenters:从Use Cases获取处理好的数据,然后根据需求逻辑为UI提供合适的数据。 UI:从Presenters获取处理好的最终数据,和用户进行直接交互。 这四层设计的原则是代码调用只能从外圆向内圆扩展,内圆不能干预也不需关心外圆的功能逻辑,这符合MVP的思想,Use Cases和Presenters将Entities和UI间隔分离,从而使Entities和UI只需关心自身逻辑,数据处理完全交给其他两层。
这里,有些同学可能会有疑问,说好的Presenters为什么会有Use Cases出来搅局?其实这也是我选择这个工程当做示例的目的,看了好多MVP文章,都在讲Presenter如何通过接口协议和其他两层进行交互,但大都忽略了Presenter层自身的构架,因为仅仅套用MVP模式,虽然在一定程度上降低View的耦合度,但因为Presenter既要处理数据,又要结合需求控制UI交互,所以很可能出现Presenter逻辑的冗余。后文的示例工程在Presenter和Model之间包装了Use Cases,将数据逻辑处理交给UseCases从而让Presenter更专心于UI交互。

(引用该文章:http://blog.csdn.net/guxiao1201/article/details/40147209)

3、MVP与MVC区别

在把原本MVC模式的代码修改为MVP模式后,总结这两个模式在实际使用过程中的不同点基本上总结为两点: 各个层之间通过接口协议进行沟通; View和Model不再进行直接交互;

(详细说明请参考MVC
or MVP Pattern - Whats the difference?

4、实战演习

模拟登录功能,实现MVP架构模式。下面是实战的具体步骤

NO1、新建VIew公共部分接口:

/**
 * Created by Bluesky on 2015/8/27.
 * MVP中V层的公共接口
 */

public interface IView {
public void showProgressPar();

public void hideProgressPar();

public void showError(Object o);
}

View继承公共IView接口

/**
 * Created by Bluesky on 2015/8/27.
 * 登录View接口
 */

public interface ILogin extends IView {
 public void showSuccess(Object o);
}

NO2、VIew的实现。也就是Activity实现ILogin接口:

/**
 *登录页面Activity
 */
public class MainActivity extends Activity implements ILogin {
private LoginPresenter mPresenter;
private User mUser;
private ProgressDialog mDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPresenter = new LoginPresenter(this);
    mUser = new User();

    initVIew();
}

private void initVIew() {
    final EditText pwd = (EditText) findViewById(R.id.pwd);
    final EditText name = (EditText) findViewById(R.id.name);
    Button loginBtn= (Button) findViewById(R.id.login_btn);
    loginBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mUser.setName(name.getText().toString());
            mUser.setPassword(pwd.getText().toString());
            mPresenter.login(mUser);
        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void showSuccess(Object o) {
    User user= (User) o;
   Toast.makeText(this,"登录成功信息:"+user.getName()+" /"+user.getPassword(),Toast.LENGTH_LONG).show();
}

@Override
public void showProgressPar() {
    mDialog = new ProgressDialog(MainActivity.this);
    mDialog.setMessage("正在加载...");
    mDialog.show();
}

@Override
public void hideProgressPar() {
    mDialog.hide();
}

@Override
public void showError(Object o) {
    Toast.makeText(this,"异常:"+((Exception)o).getMessage(),Toast.LENGTH_LONG).show();

}
}

activity的xml布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".MainActivity"
>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world"/>

<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
/>

<EditText
android:id="@+id/pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
/>

<Button
android:id="@+id/login_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"/>

</LinearLayout>

No3、新建LoginPresenter。我们面向接口编程,所以,新建一个Presenter接口,在该Demo是没有什么方法,这是为了可扩展性考虑。 presenter接口

/**
 * Created by Bluesky on 2015/8/27.
 * MVP中P层
 */

public interface Presenter {

}

登录presenter实现presenter接口,在这里进行View和Model层桥梁连接,进行业务调度,起到指挥作用

/**
 * Created by Bluesky on 2015/8/27.
 */

public class LoginPresenter implements Presenter {
private ILogin mLoginView;
private ILoginBiz mLoginBiz;
private Handler mHandler = new Handler();

public LoginPresenter(ILogin mLoginView) {
    this.mLoginView = mLoginView;
    this.mLoginBiz = new LoginBizImpl();
}

/**
 * 登录
 *
 * @param o
 */
public void login(Object o) {
    mLoginView.showProgressPar();
    mLoginBiz.login(o, new Listener() {
        @Override
        public void complete() {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mLoginView.hideProgressPar();
                }
            });
        }

        @Override
        public void onSuccess(final Object o) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mLoginView.showSuccess(o);
                }

            });
        }

        @Override
        public void onFailed(final Exception e) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mLoginView.showError(e);
                }
            });

        }
    });
}
}

No4、Model层进行业务逻辑处理。新建model层接口,然后实现业务逻辑处理,做异步处理及子线程和主线程通讯。 model接口:

/**
 * Created by Bluesky on 2015/8/27.
 */
public interface ILoginBiz {
public void login(Object o,Listener listener);
}

model实现:

/**
 * Created by Bluesky on 2015/8/27.
 */
public class LoginBizImpl implements ILoginBiz {
@Override
public void login(Object o, final Listener listener) {
final User user = (User) o;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
listener.complete();
if (user.getName().equals(user.getPassword())) {//成功
listener.onSuccess(user);
} else {//失败
listener.onFailed(new Exception("运行异常..."));
}
}
}).start();
}
}

实体类:

/**
 * Created by Bluesky on 2015/8/27.
 */

public class User implements Serializable {
private String name;
private String password;

public String getPassword() {
return password;
}

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

public String getName() {
return name;

}

public void setName(String name) {
this.name = name;
}
}

回调接口:

/**
 * Created by Bluesky on 2015/8/27.
 */
public interface Listener {
public void complete();

public void onSuccess(Object o);

public void onFailed(Exception e);
}

源代码

https://github.com/hrx3627/MVPAndroidDemo

参考信息

http://www.imooc.com/wenda/detail/216700http://www.cnblogs.com/daizhj/archive/2009/04/30/1447035.HTMLhttp://blog.csdn.net/lmj623565791/article/details/46596109http://zhengxiaopeng.com/2015/02/06/Android中的MVP/http://blog.csdn.net/guxiao1201/article/details/40147209

个人信息

  • 微信:huangrx1988
  • 博客:http://blog.csdn.net/hrx3627
  • github:https://github.com/hrx3627
  • Android交流QQ群 :367818514
  • QQ:1084986314

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-04 15:22:46

如何使用MVP架构Android应用项目的相关文章

MVP架构-Android官方MVP项目和响应式MVP-RxJava项目架构分析对比解读

介绍 MVP这个架构一直是Android开发社区讨论的焦点,每个人都有自己的分析理解众说纷纭.直到GitHub上Google官方发布用MVP架构搭建的项目.感觉是时候分析了. MVP架构简介 这不是本文重点,所以摘抄自李江东的博文 MVP架构简介 对于一个应用而言我们需要对它抽象出各个层面,而在MVP架构中它将UI界面和数据进行隔离,所以我们的应用也就分为三个层次. View:对于View层也是视图层,在View层中只负责对数据的展示,提供友好的界面与用户进行交互.在Android开发中通常将A

ReadHub项目Kotlin版开发指南(三、MVP架构)

ReadHub项目Kotlin版转换指南(一.环境搭建) ReadHub项目Kotlin版转换指南(二.数据库和网络请求) ReadHub项目Kotlin版转换指南(三.MVP架构) Android 开发中的 MVP 架构相信大家都已经熟悉,不熟悉的请右转 Google,ReadHub 项目从 Java 转换成 Kotlin 过程中,我们需要一套新的架构方式来实现(Kotlin 项目中没有使用 dagger2). base 为 MVP 架构的基础部分,user 为其具体使用过程. base Ba

Android官方MVP架构示例项目解析

前段时间Google在Github推出了一个项目,专门展示Android引用各种各样的MVP架构,算是官方教程了.趁着还新鲜,让我们来抛砖引玉一探究竟,看看在Google眼里什么样算是好的MVP架构. App架构在Android开发者中一直是讨论比较多的一个话题,目前讨论较多的有MVP.MVVM.Clean这三种.google官方对于架构的态度一直是非常开放的,让开发者自主选择组织和架构app的方式,期望能留给开发者更多的灵活性. 由于没有一套权威的架构实现,现在很多App项目中在架构方面都有或

Android开发中的MVP架构(转)

写在前面,本博客来源于公众号文章:http://mp.weixin.qq.com/s?__biz=MzA3MDMyMjkzNg==&mid=402435540&idx=1&sn=1cd10bd9efaac7083575367a8b4af52f&scene=1&srcid=0910ARzPpBvVYPI1NDBZnixa#wechat_redirect 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解MVP和DDD,但是我们的新项目

Android之MVP架构

MVP(Model View Presenter)模式是由MVC模式发展而来的,在如今的Android程序开发中显得越来越重要.本篇文章简单讨论了MVP模式的思想. 啥是MVP MVP模式的主要思想是将程序的业务逻辑从表现层分离出来,理想情况下,MVP模式可以使得相同的逻辑拥有完全不同且可互换的views. 为啥要用MVP 在Android实际开发过程中,我们会遇到这样的问题:Android中的activity与界面展示和数据访问机制耦合度非常高,既负责页面组件的展示,又负责处理业务逻辑.一个极

Android中的MVP架构初探

说来惭愧,MVP的架构模式已经在Android领域出现一两年了,但是到今天自己才开始Android领域中的MVP架构征程.闲话不多说,开始吧! 一.架构演变概述 我记得我找第一份工作时,面试官问我"android是否属于MVC架构模式,简述一下".确实,Android的整体设计结构就是MVC的设计模式,在J2EE的开发中,使用的也是MVC模式,MVC模式是一个经典,经历了几十年的考验.Android项目中的MVC架构: View:是应用程序中处理数据显示的部分,对应于layout文件下

Android MVP架构分析

App架构在Android开发者中一直是讨论比较多的一个话题,目前讨论较多的有MVP.MVVM.Clean这三种.google官方对于架构的态度一直是非常开放的,让开发者自主选择组织和架构app的方式,期望能留给开发者更多的灵活性. 由于没有一套权威的架构实现,现在很多App项目中在架构方面都有或多或少的问题.第一种常见问题是没有架构,需求中的一个页面对应项目中的一个activity或一个fragment,所有的界面响应代码.业务逻辑代码.数据请求代码等等都集中在其中.第二种常见的问题是架构实现

android MVP——mvp架构的应用和优化

MVP架构在android还是很好用的.我也在试着将mvp用在项目中. 下面我就来说说mvp模式的应用和优化. mvp模式的概念 MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示. 比较 mvc: 1,在MVC里,View是可以直接访问Model的,View里会包含Model信息,不可避免的还要包括一些业务逻辑. 2,Model不依赖于View,但是View是依赖于Model. 3,有一

开源项目Philm的MVP架构分析

前言 最近一直在研究ChrisBannes的开源项目Philm,其整体架构是一套MVP的实现,因为自己也确实没有遇到过整个项目利用MVP搭建的架构,看到的更多是一些代码片段,这里就探讨Philm是如何结合Android实际问题来实现一种MVP架构,如有分析不准确的地方,欢迎指出,大家一起探讨. 项目地址:https://github.com/Juneor/philm Philm项目运行效果图(典型的Material Design风格): 1.简单谈一谈MVP 在无任何模式下的开发时,Activi