MVP架构设计

MVP

MVP——全场最有价值球员…… 啊呸!

MVP——Model-View-Presenter分层框架模式,可以说这是MVC框架设计的变形体,事实上这两种框架也存在很多的相同点。分层方式也是将Controller改成了Presenter,当然,各层内部的定义以及相互之间的关系也做了很大改变,与MVC的区别也就体现在这里。

MVP简介

  老规矩,拆看慢慢讲。MVP分为Model、View、Presenter三层:

  Model作为模型层,在MVP中更偏向于功能的模型;

  View作为视图层,这一点和MVC基本没有差别,代表着布局和控件;

  Presenter作为主持层,也就是主持着View与Model之间的交互。

  MVP框架中,断绝了View与Model之间的直接交互,成功的减少了Activity中的臃肿代码,使得Activity能够保持整洁清晰。这一次除了讲解各层之外,还会和MVC中相同的层做个对比,毕竟刚开始从MVC转换到MVP还是很容易跑偏的。与MVC最直观的不同,MVP中定义接口完成联系。

Model

  Model是MVP中的模型层,在MVP中,通常我会用来定义功能。而在MVC中,Model的主要部分就在于Domain的定义,由于Activity中交缠了太多的东西,mvc虽然常常在分包时显得清晰,但事实上的编码部分却非常的复杂。而MVP部分将Model的职责定义的更加清晰,也就让各层的就够更加明显易见。

在这里我就用登录(Login)作为实例。

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'首先是接口'</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginModel</span>{</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用于回调登录进程</span>
    interface LoginListener{

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onLogining();

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onSuccess();

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onFaield()
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> login(String username, String password, OnLoginListener listener);

}


<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'接着是实现部分'</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginModelImpl</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginModel</span>{</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">login</span>(String username, String password, OnLoginListener listener){

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//登录逻辑...    </span>

        listener.onLogining();

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(....)
            listener.onSuccess();

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(....)
            listener.onFaield();
    }
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

  先从定义的接口讲起,LoginModel作为接口定义Login这一功能模型,同时在接口中定义一个接口,用于监听登录的过程,作为回调使用。

  之后是接口实现,在实现类中完成功能的实现,并且在过程中根据不同情况进行回调操作。

  从这里可以初步看出,MVP模式是将各层更加清晰的进行分离了。Model的主要工作就是进行功能执行,其余的工作将会交付给Presenter完成。


View

  MVP中的View层(视图层)和MVC没有太大差别,同样是由xml文件以及Activity/Fragment完成。

  不同点在于: 
    1. MVP中的View层添加了接口定义部分 
    2. MVP中的View层不再与Model层直接进行交互,不然就不清真了。呸!不然就不解耦了。

来看一下View层中的接口定义:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> LoginView{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> showProgress();

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> hideProgress();

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> inputError(String error);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

  可以看出,在LoginView中定义的方法都是和显示有关的方法,也就是涉及到Login这一过程中将会出现的几种View表现方式。接口中所定义的所有方法,最终都是由Activity来实现的,所以在接口中的方法应该尽量考虑好参数与返回值。


Presenter

  MVP中的Presenter层,称它为主持我觉得也挺贴切,作为一个中间人主持Model与View之间的交互,在MVC中Activity内关于Model及View之间的交互都可以移入Presenter中,由Presenter完成这两层之间的交互。那么可以这么说,Presenter层在MVP中占着大比重。

首先来看看接口定义

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'看着接口定义很简单,只有一个方法定义'</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> LoginPresenter{

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> loginCheck(String username, Stirng password);

}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

接着是接口的实现类

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginPresenterImpl</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginPresenter</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginModel</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">OnLoginListener</span>{</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> LoginView loginView;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> LoginModel loginModel;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//非常重要的构造方法,联系Model和View的关键</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LoginPresenterImpl</span>(LoginView loginView){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.loginView = loginView;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.loginModel = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LoginModelImpl();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">loginCheck</span>(String username, String password){
        loginView.showProgress();
        ......
        loginView.input(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"错误信息"</span>);
        ......
        loginModel.login(username, password);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onLogining</span>(){

    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onSuccess</span>(){
        loginView.hideProgress();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFaield</span>(){
        loginView.hideProgress();
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li></ul>

Activity(View)

  Activity是应该分类到View层中的,而在本文中为了构建的整体思路更加完整丝滑,所以讲Activity中的定义部分放到最后完成。但务必注意,Activity在MVP中不是单属一层,而是属于View层

来看一下Activity的编写方式:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginView</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">View</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">OnClickListener</span>{</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> LoginPresenter loginPresenter;

    pretected <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onCreate(Bundle saveInstance){
        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'...'</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//init</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//findViewById</span>
        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'...'</span>

        loginPresenter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LoginPresenterImpl(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">showProgress</span>(){
        progressBar.setVisiable(View.Visiable);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">hideProgress</span>(){
        progressBar.setVisiable(View.InVisiable);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">inputError</span>(String error){
        Toast.makeText(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, error, Toast.LENGTH_SHORT).show();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span>(v){
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> R.id.bt_login:
                loginPresenter.checkLogin(username, password);
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        }
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li></ul>

  有没有觉得很美好,这么清楚的Activity,简直了。当然,Activity的简洁是付出了代价的。三个接口也让包结构没有MVC那么美丽的,只能说这一点上各有千秋。再重申一遍吧,除了学习需要,不要刻意的为了使用某个框架结构而去使用,这句话真帅……,选用了错误的框架结构还不如不用,这是真的,否则项目越到后期就会越可怕,可怕到你不想再碰它。

OK,那么关于MVP的讲解到这里就全部结束了,大家散了吃饭去吧。

。。。。。。

你们这些年轻人,不要动不动就提刀拔剑的,我马上接着说不就行了。


MVP各层关系梳理

  之前也提到过MVP中,断绝了Model与View之间的交互,那么也就是说MVP中层与层的关系变得简单了,不再是三角式的了。啧,没想到之前学的是这种MVC。( ̄ε(# ̄)☆╰╮( ̄▽ ̄///)

别的不说,先看张图。我可是专门下了个axure 
    这里写图片描述

  这张图可以说已经把MVP各层的关系讲述的淋漓尽致了,当然,关于各个层之间是怎样产生联系的这一点,我也会做一个详细的解析。事实上这已经在PresenterImpl的代码中体现的比较明显了。

   Model与Presenter

  在PresenterImpl的构造方法中,实例化一个ModelImpl类,完成在PresenterImpl中获取Model对象的步骤。这一部非常简单,同时有效。

   View与Presenter

  在PresenterImpl中直接以参数形式获取View对象,这一点甚至比实例化简单。通常的做法是在Activity中,实例化PresenterImpl对象,同时将this(也就是Activity本身)作为参数传入PresenterImpl的构造方法。

   Presenter完成的交互

Presenter作为MVP中的主持层,保证Model与View两层之间的相互交流。在PresenterImpl内部能够依照Model对象的状态调用View对象的方法,同时也能够在调用View对象方法之后修改Model对象状态。在Presenter中的实现就完成了Model与View之间的交互。

   Model与View之间的交互

  MVP中不应该存在Model与View直接交互的情况,这部分讲的是Model与View通过Presenter进行的间接交互,在没有黑科技的情况下(后面会提到),一般使用Listener来做一个监听,在Model中定义Listener,监听Model中各个阶段,之后通过PresenterImpl来在各个回调中处理View的动作。

MVP适用环境

  MVP模式上手以后,大家会发现按模块分开项目后,脉络确实变得很清晰,但是在有的时候就变得灰常心塞,举个例子: 
某个Activity,功能简单,一个专注页面跳转的Activity,这个时候,确定还要使用MVP吗?

  我个人还是主张灵活变化,既然这个Acitivity只存在页面跳转,那么就直接在Activity中完成就好,结构同样清晰,而且在这一情况下,MVP的代码量更多更复杂,或许结构确实清晰,但是Activity中完成这些内容也同样清晰明了。

MVP是否真的那么好用? 
并没有,甚至我在学习使用的时候感觉这玩意没有好过MVC在哪里。而事实上也确实是这样。MVC和MVP没有特定的高低分别。 
当非常迅速的需要开发一个小型时,什么解耦什么重用都是其次,那么考虑MVC吧。 为了一个追求迅速获得结果的项目,再来选用MVP就变得太过复杂了。 
当时间足够,项目在后期需要足够多的修改开发,那么可以考虑MVP,清晰的脉络很方便项目修改更新。

  完全不推崇任何一个模式框架,千万不要认定一个框架不回头,用在的不合适的框架下反而会加大开发成本,让项目变得混乱

所以MVVM的文章我决定下个月再写。。。。


MVP+Retrofit+RxJava

  以下内容算是个友情赠送,下面的内容最近挺火的,既然提到说了MVP,那么就把可以用来配合的黑科技一起给大家讲讲。

  在阅读下面内容之前请先掌握Retrofit与RxJava的基本使用方式。 
正好我也写了,顺便不要脸的打波广告:

Retrofit使用简介

RxJava使用简介

  之前已经介绍过了MVP的设计方式,那么配合Retrofit和RxJava后,就需要对之前的内容做一个修改,View模块不用做什么改动,主要的改动在Model层和Presenter层

加入Retrofit

1.创建interface

首先是Retrofit的正常步骤,先把网络请求的interface完成了。

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginServer</span>{</span>
    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@FormUrlEncoded</span>
    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@POST</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"path"</span>)
    Call<ResponseBody> login(<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@FieldMap</span> Map<String, String> map);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

2.修改Model层内容

将原先的网络请求替换为Retrofit来完成。

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在ModelImpl中使用Retrofit完成网络请求</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Call<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>ResponseBody<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> login(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> username, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> password) {
    Retrofit retrofit <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> Retrofit<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Builder()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>
                                     baseUrl(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://xxx.xxx.xx.xx/"</span>)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>
                                     addConverterFactory(GsonConverterFactory<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>create())<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>
                                     addCallAdapterFactory(RxJavaCallAdapterFactory<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>create())<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>build();
    loginServer <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> retrofit<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>create(LoginServer<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>class);

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//登录数据设置</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Map</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> HashMap<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><></span>();
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>put(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"username"</span>, username);
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>put(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"password"</span>, password);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> loginServer<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>login(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span>);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

3.修改Presenter层内容

不通过回调,使用ResponseBody来确定View的动作。

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">Call<ResponseBoay> requ = loginModel.login(username, password);

requ.enqueue(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CallBack<ResponseBody>(){
 <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onResponse</span>(Call<Person> call, Response<Person> response) {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//回调事件在UI线程中,能够进行UI操作</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据body调用view动作</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//......</span>

    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFailure</span>(Call<Person> call, Throwable t) {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//回调事件在UI线程中,能够进行UI操作</span>

    }
});

</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>

是不是很优雅,是不是很酷炫,加什么Listener,Low!!!

  开玩笑的,Listener还是很有用处的,不过配合了Retrofit代码确实变得很轻便,而且比我们自己整整HttpUrlConnection要方便的多,更何况Retrofit还做了优化整合。

加入RxJava

  加入了Retrofit以后,觉得代码又变的有点乱,没关系,加上RxJava,代码气质又上了一个档次,整个代码就会变得很油很亮,( ̄ε(# ̄)☆╰╮( ̄▽ ̄///),不是不是,是变得很优雅很整洁。

加入了RxJava,我们只要沿着Retrofit的道路逐步修改就能搞定

1.修改Interface

修改Interface的返回值,准确的说是内部方法的返回值。将原先的Call改变为Observable对象。

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LoginServer</span>{</span>
    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@FormUrlEncoded</span>
    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@POST</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"path"</span>)
    Observable<ResponseBody> login(<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@FieldMap</span> Map<String, String> map);
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

2.修改Model层

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Observable<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>ResponseBody<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> login(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> username, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> password) {
        Retrofit retrofit <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> Retrofit<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Builder()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>
                                         baseUrl(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://xxx.xxx.xx.xx/"</span>)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>
                                         addConverterFactory(GsonConverterFactory<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>create())<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>
                                         addCallAdapterFactory(RxJavaCallAdapterFactory<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>create())<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>build();
        loginServer <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> retrofit<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>create(LoginServer<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>class);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//登录数据设置</span>
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Map</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> HashMap<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><></span>();
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>put(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"username"</span>, username);
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>put(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"password"</span>, password);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> loginServer<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>login(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span>);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

3.修改Presenter层

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">loginModel.login(username,password).
           subscribeOn(Schedulers.io()).
           observeOn(AndroidSchedulers.
           mainThread()).
           subscribe(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Subscriber<ResponseBody>() {
                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCompleted</span>() {
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 完成</span>
                    loginView.hideProgress();
                }

                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onError</span>(Throwable e) {
                    loginView.hideProgress();
                }

                <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onNext</span>(ResponseBody responseBody) {
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据Response内容作出动作</span>

                }
            });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>

一步到位,从Model中的请求到处理数据到View的动作一气呵成。

以上就是MVP+Retrofit+RxJava的内容。


总结

  这一次解析MVP可以说是又一次深有体会,感触良多,很多细节方面的东西都有了新的认识,在最后还加上了Retrofit+RxJava的配合使用,真正的感觉这样的开发非常便捷有效,所以分享给大家,关于例子源码已将完成,链接分享在最下方了。再也不给自己定最后期限了,反正都会成为咸鱼。。。~(~ ̄▽ ̄)~

感谢各位读到最后,一只正在成长的程序猴希望能对你有所帮助。

MVP示例源码 https://github.com/mayemonkey/MVPSample/tree/master

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值