框架模式MVP在Android中的使用

前一篇文章中学习了MVC框架模式在Android中的使用,不了解什么是MVC框架模式的亲戳这里 框架模式 MVC 在Android中的使用。其实谷歌Android开发团队是鼓励开发者利用MVC框架模式开发项目的,我们平时写代码也或多或少的在使用MVC框架模式开发项目,比如说谷歌自己退出来的Volley网络请求框架就是遵循MVC框架的。我们可以理解为Volley框架是MVC当中的模型,也就是网络数据处理这一块,无需跟View视图有任何关联。也符合视图和模型分离。可能你会觉得MVC框架已经很好用了,也能满足任何项目开发,不错,可是从上一篇博客你会发现,Controller控制器和View视图显示是在一个类Activity中体现出来的,而Android中Activity是担当Controller控制器的角色的,如果界面操作方式繁琐,视图显示复杂,那么我们不得不在Activity中添加更多的View视图显示操作,这样自然增加了Activity的代码量,也导致了Activity承担的任务和逻辑处理太多,职责不清晰。这一篇我们来介绍另外一种框架模式MVP。

MVP

MPV 是从经典的MVC模式演变过来的,其基本思路都是相通的。其中M是model模型,提供业务数据;P和MVC中的C担当的角色相似,是Presenter控制者,进行逻辑处理。V是View视图,显示数据。MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。

MVC框架图

MVP框架图

从上面的框架图可以看出MVC和MVP最大的区别就是 Model和View之间的关系。在MVC框架中,View是可以直接读取Model模型中的数据的,Model模型数据发生改变是会通知View数据显示发生相应的改变。而在MVP中Model和View之间的没有任何联系,是两个完全独立的模块,当Model模型发生数据改变时,通过Presenter通知View视图发生相应的UI改变。因此,个人觉得:MVP才是正真的视图和模型完全分离,也就是Model模型进行业务数据处理和View视图显示没有任何关联。

MVP for Android

在Andorid项目中,我们习惯将Activity作为MVC中的控制者来达到Model模型和View视图分离,但是在MVP框架模式中,通常将Activity作为View视图层,因为在MVC框架模式中Activity和View视图显示关联紧密,Activity中包含大量的View视图显示代码,如果哪天老板说需要修改View视图显示,这时候你是不是感觉需要修改Activity中的大量代码?这么一来会将Activity中控制逻辑破坏,也导致Activity中承担太多的职责。根据单一职责原则,Activity主要起到用户交互作用,也就是接收用户输入,显示请求结果。因此可以通过MVP框架模式来减轻Activity的职责。看看Android项目中怎么实现吧!

同样拿上一篇的天气预报小项目来举例子:

Model模型

和MVC框架模式一样,Model模型处理数据代码不变

/**
 * Created by xjp 2015-6-7
 * 天气Model接口
 */
public interface WeatherModel {
    void loadWeather(String cityNO, OnWeatherListener listener);
}
.........

/**
 * Created by xjp on 2015/6/7.
 * 天气Model实现
 */
public class WeatherModelImpl implements WeatherModel {
    @Override
    public void loadWeather(String cityNO, final OnWeatherListener listener) {
        /*数据层操作*/
        VolleyRequest.newInstance().newGsonRequest("http://www.weather.com.cn/data/sk/" + cityNO + ".html",
                Weather.class, new Response.Listener<Weather>() {
                    @Override
                    public void onResponse(Weather weather) {
                        if (weather != null) {
                            listener.onSuccess(weather);
                        } else {
                            listener.onError();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        listener.onError();
                    }
                });
    }
}

通过OnWeatherListener接口回调将Model模型处理的数据返回给Presenter控制者。

Presenter控制器

/**
 * Created by xjp on 2015/6/7.
 * 天气 Presenter接口
 */
public interface WeatherPresenter {
    /**
     * 获取天气的逻辑
     */
    void getWeather(String cityNO);

}
..........

/**
 * Created by xjp on 2015/6/7.
 * 在Presenter层实现,给Model层回调,更改View层的状态,确保Model层不直接操作View层
 */
public interface OnWeatherListener {
    /**
     * 成功时回调
     *
     * @param weather
     */
    void onSuccess(Weather weather);
    /**
     * 失败时回调,简单处理,没做什么
     */
    void onError();

}

.........

package org.rocko.demos.mvp.presenter.impl;

import org.rocko.demos.mvp.model.WeatherModel;
import org.rocko.demos.mvp.model.entity.Weather;
import org.rocko.demos.mvp.model.impl.WeatherModelImpl;
import org.rocko.demos.mvp.presenter.OnWeatherListener;
import org.rocko.demos.mvp.presenter.WeatherPresenter;
import org.rocko.demos.mvp.ui.view.WeatherView;

/**
 * Created by xjp on 2015/6/7.
 * 天气 Presenter实现
 */
public class WeatherPresenterImpl implements WeatherPresenter, OnWeatherListener {
    /*Presenter作为中间层,持有View和Model的引用*/
    private WeatherView weatherView;
    private WeatherModel weatherModel;

    public WeatherPresenterImpl(WeatherView weatherView) {
        this.weatherView = weatherView;
        weatherModel = new WeatherModelImpl();
    }

    @Override
    public void getWeather(String cityNO) {
        weatherView.showLoading();
        weatherModel.loadWeather(cityNO, this);
    }

    @Override
    public void onSuccess(Weather weather) {
        weatherView.hideLoading();
        weatherView.setWeatherInfo(weather);
    }

    @Override
    public void onError() {
        weatherView.hideLoading();
        weatherView.showError();
    }
}

从代码中我们可以看到Presenter控制器同时持有 WeatherModel和WeatherView对象且实现了OnWeatherListener接口取回Model模型数据,因此,WeatherPresenterImpl向WeatherModel发送数据请求,然后通过OnWeatherListener接口实现获取请求结果,在将结果通过接口WeatherView把数据显示到Activity担当的View视图中。从而达到彻底将Model和View完全分离,试想在这种情况下,如果你需要修改Model是完全不会影响View视图代码的修改的,同理,修改View视图层的时候,也完全无需修改Model层。相当于Model和View互相不知道对方的存在,都是通过中间控制器Presenter来传达通信。

View视图

先定义一个View视图显示的接口WeatherView

/**
 * Created by xjp on 2015/6/7.
 */
public interface WeatherView {
    void showLoading();

    void hideLoading();

    void showError();

    void setWeatherInfo(Weather weather);
}

然后实现Activity实现WeatherView接口

/**
 * 天气界面
 */
public class WeatherActivity extends BaseActivity implements WeatherView, View.OnClickListener {
    private Dialog loadingDialog;
    private EditText cityNOInput;
    private TextView city;
    private TextView cityNO;
    private TextView temp;
    private TextView wd;
    private TextView ws;
    private TextView sd;
    private TextView wse;
    private TextView time;
    private TextView njd;

    private WeatherPresenter weatherPresenter;

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

    }

    private void init() {
        cityNOInput = findView(R.id.et_city_no);
        city = findView(R.id.tv_city);
        cityNO = findView(R.id.tv_city_no);
        temp = findView(R.id.tv_temp);
        wd = findView(R.id.tv_WD);
        ws = findView(R.id.tv_WS);
        sd = findView(R.id.tv_SD);
        wse = findView(R.id.tv_WSE);
        time = findView(R.id.tv_time);
        njd = findView(R.id.tv_njd);

        findView(R.id.btn_go).setOnClickListener(this);

        weatherPresenter = new WeatherPresenterImpl(this); //传入WeatherView
        loadingDialog = new ProgressDialog(this);
        loadingDialog.setTitle("加载天气中...");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_go:
                weatherPresenter.getWeather(cityNOInput.getText().toString().trim());
                break;
        }
    }

    @Override
    public void showLoading() {
        loadingDialog.show();
    }

    @Override
    public void hideLoading() {
        loadingDialog.dismiss();
    }

    @Override
    public void showError() {
        //Do something
        Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void setWeatherInfo(Weather weather) {
        WeatherInfo info = weather.getWeatherinfo();
        city.setText(info.getCity());
        cityNO.setText(info.getCityid());
        temp.setText(info.getTemp());
        wd.setText(info.getWD());
        ws.setText(info.getWS());
        sd.setText(info.getSD());
        wse.setText(info.getWS());
        time.setText(info.getTemp());
        njd.setText(info.getNjd());
    }

}

因此,Activity及从MVC中的Controller中解放出来了,这会Activity主要做显示View的作用和用户交互。每个Activity可以根据自己显示View的不同实现View视图接口WeatherView。

总结

  1. MVP框架模式完全将Model模型和View视图分离,从而使得代码的耦合性第,利用MVP框架写项目达到解耦作用。
  2. MVP和MVC最大的区别是:MVC中的V可以从M中获取数据,而MVP中M和V完全分离,互相不知道对方的存在,Presenter通过接口通信方式将V和M通信。
  3. 在Android中MVP框架 Activity担当View视图层和MVC框架模式不一样Activity担当控制器。

源码地址下载:源码地址

时间: 2024-10-13 07:40:49

框架模式MVP在Android中的使用的相关文章

框架模式 MVC 在Android中的使用

算来学习Android开发已有2年的历史了,在这2年的学习当中,基本掌握了Android的基础知识.越到后面的学习越感觉困难,一来是自认为android没啥可学的了(自认为的,其实还有很多知识科学),二来网络上的很多框架已经帮我们做了太多的事情了,我们只需要画画UI就可以了,感觉Android开发没有太多的技术含金量.最近闲来无事,开始总结之前学过的知识点,想着是否应该学点其他的东西呢?总不能局限于Android基础知识吧.慢慢的探索发现在大的项目工程中,一个好的框架,好的设计模式,能减少很大的

[转]框架模式 MVC 在Android中的使用

算来学习Android开发已有2年的历史了,在这2年的学习当中,基本掌握了Android的基础知识.越到后面的学习越感觉困难,一来是自认为android没啥可学的了(自认为的,其实还有很多知识科学),二来网络上的很多框架已经帮我们做了太多的事情了,我们只需要画画UI就可以了,感觉Android开发没有太多的技术含金量.最近闲来无事,开始总结之前学过的知识点,想着是否应该学点其他的东西呢?总不能局限于Android基础知识吧.慢慢的探索发现在大的项目工程中,一个好的框架,好的设计模式,能减少很大的

框架模式MVC与MVP在Android中的应用

很多人在开发Android项目时没有考虑过架构模式的问题,以至于随着项目的增大,Activty或者Fragment中代码也会越来越多,导致项目的维护变的越来越复杂.然而在Android中使用比较多的两种框架模式就是MVC和MVP,下面我将分别介绍一下这两种框架模式. 一.MVC框架模式 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑

简述MVC框架模式以及在你(Android)项目中得应用

标题是阿里电话面试的问题,一直以为自己很清楚MVC模式,结果被问到时,这M.V.C这几者之间的关系都搞不清楚了,最主要是,没法将MVC和Android中各个组件对应起来,所以,面试肯定挂了,不过面试也是学习的一种方式,可以知道大公司看中什么,以及自己还有哪些知识漏洞,例如这次面试就学到了很多东西. 大家也可以在看下面的内容之前,也想想能否把MVC及与Android各个组件的对应关系讲清楚,看是否还有和我一样对MVC一知半解的.  如果写的有问题的地方,欢迎讨论.转载请注明出处:http://ww

Android中Activity启动模式详解,可以控制程序按home键后进来还会调用一个自己不喜欢的界面

其实这是很简单的一个问题.但是这还是要对android中activity的启动模式有相当的理解才行,当点击home键的时候,懂Android的人都知道,他会把当前activity放到后退栈中, 栈(Stack)又称堆栈,它是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算.人们把此端称为栈顶,栈顶的第一个元素被称为栈顶元素,相对地,把另一端称为栈底.向一个栈插入新元素又称为进栈或入栈,它是把该元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称为出栈或退栈,它是把栈

[转] Android中的设计模式-备忘录模式

转自Android中的设计模式-备忘录模式 定义 备忘录设计模式的定义就是把对象的状态记录和管理委托给外界处理,用以维持自己的封闭性. 比较官方的定义 备忘录模式(Memento Pattern)又叫做快照模式(Snapshot Pattern)或Token模式,是GoF的23种设计模式之一,属于行为模式. 定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 角色 笔记本:很多的内部状态需要被建立一个备忘录来管理,创建和取出

SSH----MVC框架模式与分层架构

MVC框架模式 MVC框架模式是web开发中一种软件设计典范,他的全名是(Model -View -Controller),是模型(model)--视图(view)--控制器(controller)的缩写,用一种业务逻辑.数据控制.界面显示分离的方式组织代码, 实现代码的模块化设计. Model,意为数据模型,该块封装了对数据的处理(底层封装了对数据库的操作) Controller,意为控制器,该块获取用户输入,并控制数据到Model模块进行逻辑处理. View,意为界面,该块从model模块获

Android MVP框架模式

结合前一篇MVC框架模式 为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生. 在MVP模式里通常包含4个要素: (1)View:负责绘制UI元素.与用户进行交互(在Android中体现为Activity); (2)View interface:需要View实现的接口,View通过View interface与Presenter

android中MVC,MVP和MVVM三种模式详解析

我们都知道,Android本身就采用了MVC模式,model层数据源层我们就不说了,至于view层即通过xml来体现,而 controller层的角色一般是由activity来担当的.虽然我们项目用到了MVP模式,但是现在人们并没有总结出一种规范,所以MVP模式的写法并不统一,而至于MVVM模式看网上的呼声似乎也是赞同和拍砖的参半,所以对于这几种模式我也不发表意见了,适合自己的才是最好的.下面是我看到的关于这几种模式的几篇文章,整合了一下分享给大家. ----------------------