Android技术知识我爱编程程序员

Android中MVP模式的了解及实例

2018-05-26  本文已影响19人  九尾74

Android中MVP的由来

在了解MVP之前我相信很多人已经学习过MVC这个框架了!MVP的诞生可以说是建立在MVC在安卓某些不足的方面

MVC简介

.M对应Model,代表业务数据

.V对应View,代表视图

.C对应Controller,代表控制器。

具体逻辑结构如下图所示:

来自百度百科

MVC框架将视图和数据分离,在WEB领域有着十分广泛的应用。

用户通过界面组件进行操作,也就是View层,相应的动作会传递给控制器也就是Controller层,而Controller根据自己的业务逻辑去操作数据层也就是Model,

而最终数据层的变化会同步更新到视图层。

MVC的主要目的是为了视图和数据分离,这对于开发大型软件来说更方便进行模块的划分,提高编码速度与质量。

Android中的MVC

Android世界中也经常运用到MVC模式。 

Activity对应视图界面也就是View层。 

数据库文件,Sharedprefrence,内存缓冲,磁盘缓冲等数据内容对应Model层。 

而Controller控制层基本上也由Activity层面来进行。

Android中mvc中基本动作流程

假设我们现在有这么一个需求,需要在一个界面上显示当天的天气,不仅如此,还可以通过列表项选择以往某一天的天气。 

mvc架构开发的话,大概是这样。

在layout制定相应的布局文件,然后显示在Activity上,用于显示天气信息。这对应于View层,这里的View并不是Android中开发中的组件view而是对视图的统称.

Activity在onCreate方法或者onResume方法去服务器获取数据,或者通过界面上的某个按钮之类去启动获取服务器数据的任务,这里就对应到View—>Controller,只不过这里的View和Controller对是由Activity来完成。

Controller获取到了数据之后,分别存在,内存、磁盘和数据库中,并且数据获取成功或者失败后,Activity界面需要同步更新状态。这由对应上面流程中的Controller—>Model 和Model—->View。

(这是你或许会想:MVC这思路不是很清晰吗??为什么还要整一个MVP呢?因为Android的特殊性,

使得Activity对应了MVC中的V和C,同时担任两个角色,就不符合软件设计原则的“单一职责”原则。但现实中是很多的APP代码中有这么的处境,特别是Androi原生的很多系统APK,

某些Activity动则几千行代码。 况且,随着项目的深入发展,很多逻辑很越来越复杂,Activity处理的东西也会越来越多,代码越来越臃肿。这样一来维护起来的代价就会越来越高,

这是因为View的变化会引起Controller的很多变化,反之亦然。用一句大白话来说明就是–某一段代码的变动会引起很多其他相关联的代码的改动。

MVP是基于MVC的,它的架构图如下: 

图片来自百度百科

.M(Model) 数据相关层

.V(View) 视图层,如Activity上的布局

.P(Presenter) 纽带层,用来连接Model与View.

MVP开发在Android中的基本流程 

1. View层定义View.interface,用来定义View的行为。一般由Activity或者是Fragment来实现这个接口,它定义了View视图的各种变化,如设置Textview,加载对话框,更新进度条等。

2. Model层定义Modle.interface,这个是用来定义数据层发生变化时的通知接口,因为Model不能直接与View交互,所以它与Presenter交互,然后再通过Presenter间接达到与View的交互。 

3. Presenter翻译的意思是主持人,也就是主持场合,控制节奏的意思。在这时Presenter就负责具体的业务逻辑,请求数据,把数据送到Model,或者监听Model的数据变化,接受View

层的动作,负责通过通知View层的视图变化。

类似于王者荣耀中的打野位(掌控节奏)

MVP实践

先是我们需要些的代码有哪几项:

而我们需要实现的效果则是:

1 2 3

例子本身是非常简单的,可以说用MVP简直是多此一举。

主要是说学习这个思想。

具体代码如下:

----------------------------------WetherPresenter-------------------------------

package com.example.acer.mvpdome.presenter;

import com.example.acer.mvpdome.model.IWetherImpl;

import com.example.acer.mvpdome.model.IWetherModel;

import com.example.acer.mvpdome.view.IWetherView;

public class WetherPresenter

{

IWetherModelmModel;

IWetherViewmView;

////因为Presenter持有View的引用,所以在这里要将View.interface注入到Presenter当中。

    public WetherPresenter(IWetherView mView) {

this.mView = mView;

mModel =new IWetherImpl();

}

//供View层调用,用来请求天气数据

    public void requestWetherInfo(){

getNetworkInfo();

}

private void getNetworkInfo()

{

new Thread(new Runnable() {

@Override

            public void run()

{

try {

//打开等待对话框

                showWaitingDialog();

//模拟网络耗时

                Thread.sleep(6000);

String info ="21度,晴转多云";

//保存到Model层

                saveInfo(info);

//从Model层获取数据,为了演示效果,实际开发中根据情况需要。

                  String localinfo = localInfo();

//通知View层改变视图

                  updateWetherInfo(localinfo);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

//取消对话框

                dissmissWaitingDialog();

}

}).start();

}

private void showWaitingDialog(){

if (mView !=null) {

mView.showWaitingDialog();

}

}

private void dissmissWaitingDialog(){

if (mView !=null) {

mView.dissmissWaitingDialog();

}

}

private void updateWetherInfo(String info){

if (mView !=null) {

mView.onInfoUpdate(info);

}

}

private String localInfo(){

return mModel.getInfo();

}

private void saveInfo(String info){

mModel.setInfo(info);

}

}

---------------------------------IWetherView---------------------------

package com.example.acer.mvpdome.view;

public interface IWetherView

{

/**1.显示天气信息

*2.显示获取信息等待对话框

* 3.取消显示对话框

*/

    public void  showWaitingDialog();

public void dissmissWaitingDialog();

public void onInfoUpdate(String info);

}

---------------------------MainActivity------------------------------


package com.example.acer.mvpdome.view;

import android.app.ProgressDialog;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import com.example.acer.mvpdome.R;

import com.example.acer.mvpdome.presenter.WetherPresenter;

public class MainActivityextends AppCompatActivityimplements IWetherView

{

WetherPresentermPresenter;

private TextViewmTvInfo;

private Buttonmbtn;

private ProgressDialogmDialog;

@Override

    protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mPresenter =new WetherPresenter(this);

mbtn=findViewById(R.id.mbtn);

mTvInfo=findViewById(R.id.mTvInfo);

mbtn.setOnClickListener(new View.OnClickListener() {

@Override

            public void onClick(View view) {

mPresenter.requestWetherInfo();

}

});

}

@Override

    public void showWaitingDialog()

{

runOnUiThread(new Runnable() {

@Override

            public void run()

{

if (mDialog !=null &&mDialog.isShowing())

{

mDialog.dismiss();

}

mDialog = ProgressDialog.show(MainActivity.this,"","正在获取中...");

}

});

}

@Override

    public void dissmissWaitingDialog() {

runOnUiThread(new Runnable() {

@Override

              public void run()

{

if (mDialog !=null &&mDialog.isShowing())

{

mDialog.dismiss();

}

}

});

}

@Override

    public void onInfoUpdate(final String info)

{

Log.d("-------------","onInfoUpdate: "+info);

runOnUiThread(new Runnable() {

@Override

              public void run()

{

mTvInfo.setText(info);

}

});

}

}

---------------------------------------IWetherModel-------------------------------------------

package com.example.acer.mvpdome.model;

public interface IWetherModel

{

//提供数据

    public  String  getInfo();

//存储数据

    public void setInfo(String info);

}

----------------------------------------------IWetherImpl--------------------------------------


package com.example.acer.mvpdome.model;

public class IWetherImplimplements IWetherModel

{

private Stringinfo;

@Override

    public String getInfo()

{

return info;

}

@Override

    public void setInfo(String info)

{

this.info=info;

}

}

分析:

这里可以看成三个人:主持人甲,拿着数据的人乙,负责展示的人丙。

首先是拿着数据的人乙,和model区别不大,接口,实现类!一路过基本上多可以理解

然后是负责展示的人丙,展示的方式的实现,接口,问题也不大!

最后主持人甲要做的事情就多了,因为要同时对View和Model对接,所以内部必须持有它们的接口引用

而Presenter也要开发API供View调用。 

所以Presenter要有requestWetherInfo()方法,剩下的基本都是它对其他两个的方法的调用!!

有兴趣的朋友可以继续深入研究

上一篇下一篇

猜你喜欢

热点阅读