Android中Mvp的使用实例



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


1.简介

       大家都知道并熟悉Mvc模式,Android原生使用也是采用Mvc的模式,但是却存在着它最大的问题就是职责不清晰,如果有人面试时问你你的项目中Mvc中C代表的是什么你肯定马上想都不想就回答代表的是controler,如果别人再问你那你的Controler和View之间的区别你会发现你把自己绕进去了很难描叙清楚,因为Mvc在Android中最大的缺陷就是它的controler和View是很难分离的整个项目也会显得耦合度太高,而且View与model之间是之间可以交互View与controler之间也是之间可以交互这样就会出现混乱。幸好有大牛研究出了MVP,MVP就是专门用来解决Mvc职责不清晰的问题,其中M还是代表的是model,V代表的是View,Presenter就充当了View与model之间交互的中间方,这样就避免了原来View可以与Activity进行交互,也可以与model进行交互,model也可以与Activity进行交互的混乱,现在MVP中View只与presenter交互,model只与presenter交互,职责清晰一目了然。
2.实例

     概念上基本理清了Mvc与Mvp之间的区别现在我们就以实际代码进行详细的解释,首先我们得清楚Mvp是通过接口回调的方式进行实现的,所以UI层,model层都是需要接口实现的。

    我们以一个登陆的例子来说明这个模式,因为登陆可以说是比较简单的而且可以完全覆盖我们Mvp中需要的大部分的实例。下面是登陆的图片

    1.首先不管Mvc还是Mvp模式Bean肯定是不可少的。这个UserBean也就是用户登陆的实例 ,简单明了就不多说了


   public class UserBean {
   //账号
   private   String account;
   //密码
   private   String password;

    public UserBean(String account, String password) {
        this.account = account;
        this.password = password;
    }

    public String getAccount() {

        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

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


 2.然后我们需要写,model就是业务逻辑层,这里我们还是采用接口的实现方式,因为这样内部方法一目了然也方便单元测试,我们所有的业务必须在model中使用,
   不要像Mvc中很多业务逻辑在Activity中直接使用而且需要View的支持这样很容易造成内存泄露,因为很多异步任务退居后台后但是还是保留了对当前Activity的引用
   而Java的回收机制会在内存不足的情况下回收Activity这样引用的Activity就没有了很容易内存泄露。
  
   //model接口

    public interface ILoginBiz {
     void login(String account,String password,OnLoginListener listener);
    }


   //model实现
  

    public class LoginBiz implements ILoginBiz {
      @Override
       public void login(String account, String password, final OnLoginListener listener) {
          if (!(account.equals("")&&password.equals("")))
         {
            //账号密码不为空允许登录,登录成功
              new Thread(new Runnable() {
                 @Override
                 public void run() {
                     try {
                         Thread.sleep(2000);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                         listener.loginsucess();
                 }
             }).start();
         }
         else
         {
             //账号密码为空登录失败
             listener.loginFailed();
         }
      }
   }

 3.然后就是View层,Mvp中我们都是以Activity作为View使用,明显区别于Mvc,但是我们需要把Activity的View引用提供给presenter,而且在Activity中实现回调更新界面在这里回调的方法我们抽象出来成为一个接口
  
  

  //里面的所有的方法都是用来更新UI 
  public interface ILoginView {
     String getAccount();
     String getPassWord();
     void loginSucess();
     void loginFailed();
  }


  有人会问不是说都是用来更新ui的方法吗为什么还有getAccount()和getPassWord()方法,很简单你想想因为你的View是在presenter中与model层进行交互的而不是在Activity中,那么你的账号密码肯定不能直接用
  EdtText.getText().toString()吧,所以需要一个方法来获取到account和password。

 4.最后就是presenter层了这里是用来控制View与model交互的,需要知道的是在biz的回调函数中需要使用一个handler。post(new Runnable)来更换UI的(handler.post()和handler.sendMessage()都是用来通知的),
 这里的new Runable中的方法写的就是更新UI的操作也就是UI线程,别理解为了

 怎么又重开了一个线程。其中View的接口回调可以让你在Activity中做一些更新的后续操作,

 

  public class UserLoginpre {
    private ILoginView view;
    private ILoginBiz loginBiz;
    private Handler handler=new Handler();
    public UserLoginpre(ILoginView iLoginView) {
        view=iLoginView;
        loginBiz=new LoginBiz();
    }
    public void login()
    {
        loginBiz.login(view.getAccount(), view.getPassWord(), new OnLoginListener() {
            @Override
            public void loginsucess() {
                 //更新UI线程
                 handler.post(new Runnable() {
                    @Override
                    public void run() {
                        view.loginSucess();
                    }
                });
            }

            @Override
            public void loginFailed() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        view.loginFailed();
                    }
                });
            }
        });
    }
  }

  有没有看到在UserLoginPre()构造函数中我们已经把View和model都给放在了presenter中了这样就是实现了View和model在presenter中交互,然后又通过回调函数实现了更新。

 5.最后就是Activity中代码了就一些更新操作实现了model,View的分离。
 
 

 //mvp中activity都是实现view层接口然后与presenter进行交互
 public class LoginActivity extends AppCompatActivity implements ILoginView, View.OnClickListener {

    private EditText edt_account;
    private EditText edt_password;
    private Button btn_login;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        initView();
        setListener();
    }

    public void initView()
    {
        edt_account = (EditText) findViewById(R.id.edt_account);
        edt_password = (EditText) findViewById(R.id.edt_password);
        btn_login = (Button)findViewById(R.id.btn_login);
        progressBar = (ProgressBar)findViewById(R.id.progress_bar);
    }
    public void setListener()
    {
        btn_login.setOnClickListener(this);
    }
    public void login()
    {
        UserLoginpre loginpre=new UserLoginpre(this);
        progressBar.setVisibility(View.VISIBLE);
        loginpre.login();
    }

    @Override
    public String getAccount() {
        return edt_account.getText().toString();
    }

    @Override
    public String getPassWord() {
        return edt_password.getText().toString();
    }

    @Override
    public void loginSucess() {
        progressBar.setVisibility(View.GONE);
        Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void loginFailed() {
        progressBar.setVisibility(View.GONE);
        Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
        login();
    }
  }

 

3.总结

         Mvc与Mvp的区别我们也说明了清楚大家应该也从代码中感觉到了区别,具体使用还是需要自己写写例子用用,那么Mvp这么好有什么缺点吗,其实还是有的从代码量可以看出来多了不少,

   因为使用了大量的接口而且多了一个presenter层,UI与业务必须写成接口,但是这样也有好处,好处就是让你在写代码前一定得自己先理清楚业务逻辑,不至于像以前一样一个复杂的页面

  Activity内的代码都是上千行,阅读难度大也高耦合不便于修改,而且很多可以抽出的方法都不能再其他页面使用。

 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值