MVP模式是MVC模式在Android上的一种变体,要了解MVP就得先了解MVC。在MVC模式中,Activity应该是属于View这一层。而实质上,它既承担了View,同时也包含一些Controller的东西在里面。这对于开发与维护来说不太友好,耦合度大高了。把Activity的View和Controller抽离出来就变成了View和Presenter,这就是MVP模式。
一、MVC模式
MVC模式的结构分为三部分,实体层的Model,视图层的View,以及控制层的Controller。
其中View层其实就是程序的UI界面,用于向用户展示数据以及接收用户的输入而Model层就是JavaBean实体类,用于保存实例数据 Controller控制器用于更新UI界面和数据实例
二、MVP模式
MVP模式的核心思想
MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model。这就是MVP模式,现在这样的话,Activity的工作的简单了,只用来响应生命周期,其他工作都丢到Presenter中去完成。从上图可以看出,Presenter是Model和View之间的桥梁,为了让结构变得更加简单,View并不能直接对Model进行操作,这也是MVP与MVC最大的不同之处。
MVP模式的作用
分离了视图逻辑和业务逻辑,降低了耦合Activity只处理生命周期的任务,代码变得更加简洁 视图逻辑和业务逻辑分别抽象到了View和Presenter的接口中去,提高代码的可阅读性 Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单元测试 把业务逻辑抽到Presenter中去,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露和OOM
其中主最要的是:1,简化了Activity的代码数量,使之更加加简介清晰;2,方便进行单元测试;3,有效的避免Activity的内存泄漏。
三、简单的Login Demo
1.项目结构
2.代码
package com.zhoujp.mvpdemo.biz; public interface IUserBiz { public void login(String username, String password, OnLoginListener loginListener); }
package com.zhoujp.mvpdemo.bean; public class UserBean { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package com.zhoujp.mvpdemo.biz; import com.zhoujp.mvpdemo.bean.UserBean; public interface OnLoginListener { void loginSuccess(UserBean user); void loginFailed(); }
package com.zhoujp.mvpdemo.biz; import com.zhoujp.mvpdemo.bean.UserBean; public class UserBiz implements IUserBiz { @Override public void login(final String username, final String password, final OnLoginListener loginListener) { // 模拟子线程耗时操作 new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 模拟登录成功 if ("zhoujp".equals(username) && "123".equals(password)) { UserBean user = new UserBean(); user.setUsername(username); user.setPassword(password); loginListener.loginSuccess(user); } else { loginListener.loginFailed(); } } }.start(); } }
package com.zhoujp.mvpdemo.presenter; import com.zhoujp.mvpdemo.bean.UserBean; import com.zhoujp.mvpdemo.biz.IUserBiz; import com.zhoujp.mvpdemo.biz.OnLoginListener; import com.zhoujp.mvpdemo.biz.UserBiz; import com.zhoujp.mvpdemo.view.IUserLoginView; import android.os.Handler; public class UserLoginPresenter { private IUserBiz userBiz; private IUserLoginView userLoginView; private Handler mHandler = new Handler(); public UserLoginPresenter(IUserLoginView userLoginView) { this.userLoginView = userLoginView; this.userBiz = new UserBiz(); } public void login() { userLoginView.showLoading(); userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(final UserBean user) { // 需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.toMainActivity(user); userLoginView.hideLoading(); } }); } @Override public void loginFailed() { // 需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.showFailedError(); userLoginView.hideLoading(); } }); } }); } public void clear() { userLoginView.clearUserName(); userLoginView.clearPassword(); } }
package com.zhoujp.mvpdemo.view; import com.zhoujp.mvpdemo.bean.UserBean; public interface IUserLoginView { String getUserName(); String getPassword(); void clearUserName(); void clearPassword(); void showLoading(); void hideLoading(); void toMainActivity(UserBean user); void showFailedError(); }
package com.zhoujp.mvp; import com.example.simplelogindemo.R; import com.zhoujp.mvpdemo.bean.UserBean; import com.zhoujp.mvpdemo.presenter.UserLoginPresenter; import com.zhoujp.mvpdemo.view.IUserLoginView; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.Toast; public class MainActivity extends Activity implements IUserLoginView { private EditText edt_name, edt_pass; private Button btn_login, btn_clear; private ProgressBar mPbLoading; private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { edt_name = (EditText) findViewById(R.id.edt_name); edt_pass = (EditText) findViewById(R.id.edt_pass); btn_login = (Button) findViewById(R.id.btn_login); btn_clear = (Button) findViewById(R.id.btn_clear); mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading); btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.login(); } }); btn_clear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mUserLoginPresenter.clear(); } }); } @Override public String getUserName() { return edt_name.getText().toString(); } @Override public String getPassword() { return edt_pass.getText().toString(); } @Override public void clearUserName() { edt_name.setText(""); } @Override public void clearPassword() { edt_pass.setText(""); } @Override public void showLoading() { mPbLoading.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mPbLoading.setVisibility(View.GONE); } @Override public void toMainActivity(UserBean user) { Toast.makeText(this, user.getUsername() + " login success , to MainActivity", Toast.LENGTH_SHORT).show(); } @Override public void showFailedError() { Toast.makeText(this, "login failed", Toast.LENGTH_SHORT).show(); } }
转载请注明原文地址: https://ju.6miu.com/read-678854.html