Giter Site home page Giter Site logo

mvp's Introduction

Android MVP 实践之路(一)

一.简单介绍下MVP

1.什么是mvp?

简称:MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本**有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

2.mvp 与mvc 的区别?

在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

3.优点和缺点介绍

优点:

  1. 模型与视图完全分离,我们可以修改视图而不影响模型
  2. 可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
  3. 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
  4. 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

缺点:

  1. 由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。比如说,原本用来呈现Html的Presenter现在也需要用于呈现Pdf了,那么视图很有可能也需要变更。

二.看下实现的效果图

三.接下来是代码实现的过程

1.从创建开始
  1. 打开Android Studio 然后新建一个工程;
  2. 在工程中,新建三个包,分个层,分别是modle、view、presenter
  3. 思考下我们要实现的功能,模拟网络请求,然后点击Button,实现页面上的TextView的文字改变,这中间我们用Handler模拟一下网络请求
  4. 思考一下我们在MVC的时候,Activity要实现的方法:
  • 点击按钮请求数据
  • 当数据请求成功后,调用此接口显示数据
  • 当数据请求失败后,调用此接口提示
  • 当数据请求异常,调用此接口提示
  • 显示正在加载进度框
  • 隐藏正在加载进度框
  1. 根据上面分析在MVC中所要实现的方法,我们来实现在MVP的View层的接口中需要实现这几个方法;
public interface MvpView {
    /**
     * 显示正在加载进度框
     */
    void showLoading();
    /**
     * 隐藏正在加载进度框
     */
    void hideLoading();
    /**
     * 当数据请求成功后,调用此接口显示数据
     * @param data 数据源
     */
    void showData(String data);
    /**
     * 当数据请求失败后,调用此接口提示
     * @param msg 失败原因
     */
    void showFailureMessage(String msg);
    /**
     * 当数据请求异常,调用此接口提示
     */
    void showErrorMessage();
}	
  1. 我们的View层好像写好了,接下来我们来想想我们的model层吧。其实很简单,我们说了model层是数据获取传输的层,那么在model中创建个model类,然后写一个获取数据的静态方法,这是获取到数据了,那么我们获取到的数据怎么传递给我们的Presenter呢? 不饶了,利用接口Callback方法来进行数据的回调;两段代码如下:

MvpModel类

public class MvpModel {
    /**
     * 获取网络接口数据
     *
     *
     * @param param    请求参数
     * @param callback 数据回调接口
     */
    public static void getNetData(final String param, final MvpCallback callback) {
        // 利用postDelayed方法模拟网络请求数据的耗时操作
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                callback.onSuccess("模拟网络请求得到的数据");
                callback.onComplete();
            }
        }, 2000);
    }
	}

MvpCallback类

public interface MvpCallback {
    /**
     * 数据请求成功
     *
     * @param data 请求到的数据
     */
    void onSuccess(String data);

    /**
     * 使用网络API接口请求方式时,虽然已经请求成功但是由
     * 于{@code msg}的原因无法正常返回数据。
     */
    void onFailure(String msg);

    /**
     * 请求数据失败,指在请求网络API接口请求方式时,出现无法联网、
     * 缺少权限,内存泄露等原因导致无法连接到请求数据源。
     */
    void onError();

    /**
     * 当请求数据结束时,无论请求结果是成功,失败或是抛出异常都会执行此方法给用户做处理,通常做网络
     * 请求时可以在此处隐藏“正在加载”的等待控件
     */
    void onComplete();
    
	}
  1. 如上方法实现后,那我们的View和model层都有了,我们要实现presenter层,这个是作为中间转换成,要实现model层和view层的方法;所以要传递一个实现View接口的窗口视图进来,然后调用model层的数据获取方法,将model层的数据展示给我我们的view哦;啥都不说了,代码看一眼就懂了;

MvpPresenter类

public class MvpPresenter {
    // View接口
    private MvpView mView;

    public MvpPresenter(MvpView view) {
        this.mView = view;
    }
    /**
     * 获取网络数据
     *
     * @param params 参数
     */
    public void getData(String params) {
        //显示正在加载进度条
        mView.showLoading();
        // 调用Model请求数据
        MvpModel.getNetData(params, new MvpCallback() {
            @Override
            public void onSuccess(String data) {
                //调用view接口显示数据
                mView.showData(data);
            }

            @Override
            public void onFailure(String msg) {
                //调用view接口提示失败信息
                mView.showFailureMessage(msg);
            }

            @Override
            public void onError() {
                //调用view接口提示请求异常
                mView.showErrorMessage();
            }

            @Override
            public void onComplete() {
                // 隐藏正在加载进度条
                mView.hideLoading();
            }
        });
    }
	}
  1. 是不是很刺激?看看自己都写了什么❓,下面就是见证奇迹的时刻,我们的mainActivity中应该如何编写?布局文件很简单,就是一个线性布局,里面一个Button,一个TextView;在Activity中,要实例化Presenter类,并且那几个方法都在Presenter中实现了哦,在来一个dialog展示框就行了,对不对?上代码看看吧,会好理解一些;

MainActivity 类

public class MainActivity extends AppCompatActivity implements MvpView {

    private ProgressDialog progressDialog;
    private MvpPresenter presenter;
    private TextView textview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textview = findViewById(R.id.textview);
        progressDialog = new ProgressDialog(this);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("正在加载数据");
        presenter = new MvpPresenter(this);

    }

    /**
     * 点击事件
     * @param view
     */
    public void getDatas(View view) {
        presenter.getData("normal");
    }

    /**
     * 显示正在加载进度框
     */
    @Override
    public void showLoading() {
        if (!progressDialog.isShowing()) {
            progressDialog.show();
        }
    }

    /**
     * 隐藏正在加载进度框
     */
    @Override
    public void hideLoading() {
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    /**
     * 当数据请求成功后,调用此接口显示数据
     *
     * @param data 数据源
     */
    @Override
    public void showData(String data) {
        textview.setText(data);
    }

    /**
     * 当数据请求失败后,调用此接口提示
     *
     * @param msg 失败原因
     */
    @Override
    public void showFailureMessage(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * 当数据请求异常,调用此接口提示
     */
    @Override
    public void showErrorMessage() {
        Toast.makeText(this, "网络请求数据出现异常", Toast.LENGTH_SHORT).show();
    }

	}

四.如上就是实现的过程,这是一个简单的demo,帮助我们理解和熟悉MVP到底是什么玩意,真的想要在项目中实践,还需要花费一番功夫来弄。这个简单的demo先分享给大家,更多的MVP的内容,我会在下面的文章中更新,欢迎大家一起交流,感谢大家;

最后附上一个GitHub的下载地址 https://github.com/softwareboy92/MVP

mvp's People

Stargazers

 avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.