Android中MVP的使用

xiaoxiao2021-02-28  130

AndroidMVP的使用

以前在写项目的时候,没有过多考虑架构模式的问题,所以一开始使用的都是类似MVC的架构,严格来讲,之前的项目都不算MVC模式,只是简单的将网络请求与界面分离,然后通过Handler通知更新界面。随着项目越来越大,Activity和Fragment中代码越来越多,导致项目的维护变得越来越复杂,一开始重构成了MVC模式,随着深入了解,发现MVP模式能够大大减少Model和View层之间的耦合度,遂又将项目重构成MVP模式。最近又发现MVP已经开始不能满足需求,正在研究MVVM,后期会将MVVM的研究成果奉上。

当然不是所有的模块都使用MVP,MVP适合在一些逻辑复杂的模块中使用,如果业务逻辑简单,一个Activity就能搞定,也没有必要生搬硬套的做成MVP模式的。只要整体的模式思路使用MVP模式,其中夹杂一些MVC模式,甚至简单的模块不使用模块,不会对整个项目有太大的影响,反而是最优选择。

MVP模式也有其缺点,首先就是代码量多了,文件数量大大提升,但换来的好处是项目结构清晰,在前期只有原型图的时候,我们也可以提前开发,Model层负责数据的请求和数据的处理,写好Presenter层和View层后,基本不用改,只需关注Model层的变化就可以了;还是就是Activity内部类基本不再使用了,部分UI逻辑判断也可以转到Presenter去处理,View层(UI)也非常清晰干净。

什么是MVP

MVP是 模型(Model)、视图(View)、主持人(Presenter)的缩写,代表不同模块。

模型(Model):负责处理数据的加载或者存储;比如从网络或者本地数据库获取数据。

视图(View):负责界面数据的展示,与用户进行交互。

主持人(Presenter):相当于协调者,是Model和View层之间的桥梁,占据主导地位。

 

如图所示,Model层和View并不直接交互,而是通过Presenter层进行交互。Presenter持有Model层和View层的Interface的引用,而View层持有Presenter层Interface的引用。当View层需要展示数据的时候,会调用Presenter层的某个接口,然后Presenter层会调用Model层请求数据,当Model层数据获取成功后会调用Presenter层的回调方法通知Presenter层数据加载完毕,然后Presenter层再调用View层的接口将获取到的数据展示给用户。

整个过程,View层告知Presenter层需要什么数据,Presenter层调用Model获取数据,Model数据获取完成告知Presenter层,Presenter层再调用View层将数据展示给用户。

这样分层减少了Model层和View层的耦合度:

1、可以使得Model层和View层单独开发与测试,互补依赖;

2、可以将Model层封装复用,减少代码量

3、方便构建单元测试,测试逻辑中存在的潜在BUG

4、清晰的结构,便于维护

准备工作

创建LoginBean

public class LoginBean {     private String mName;     private String mPassWord;     public String getmName(){         return mName;     }     public void setmName(String name){         mName = name;     }     public String getmPassWord(){         return mPassWord;     }     public void setmPassWord(String passWord){         mPassWord = passWord;     } }

 

模型层(Model

1. 先写一个接口

public interface ILoginModel {     void login(String username, String password, OnLoginListener loginListener);     interface OnLoginListener{         void LoginSuccess(LoginBean loginBean);         void LoginFail();     } }

2. 继承接口进行数据请求

public class LoginModel implements ILoginModel {     @Override     public void login(String username, String password, OnLoginListener loginListener) {         //模拟子线程耗时操作         simulationRequest(username, password, loginListener);     }     private void simulationRequest(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(username.equals("Lking") && password.equals("123456")){//登录成功                     LoginBean loginBean = new LoginBean();                     loginBean.setmName(username);                     loginBean.setmPassWord(password);                     loginListener.LoginSuccess(loginBean);                 }else{//登录失败                     loginListener.LoginFail();                 }             }         }.start();     } }

视图层(View

1、先写一个接口

public interface ILoginView {     /** 获取账号*/     String getName();     /** 获取密码*/     String getPassword();     /** 显示加载圈*/     void showLoading();     /** 关闭加载圈*/     void hideLoading();     /** 跳转到主界面*/     void toMainActivity(LoginBean loginBean);     /** 显示失败提示*/     void showFailToast(); }

2、编写布局文件activity_mvp.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:background="@color/color_ffffff"     android:orientation="vertical">     <LinearLayout         android:layout_width="match_parent"         android:layout_height="45dp"         android:layout_margin="10dp">         <TextView             android:layout_width="wrap_content"             android:layout_height="match_parent"             android:gravity="center"             android:text="账    号:"             android:textColor="@color/color_000000"             android:textSize="18sp" />         <EditText             android:id="@+id/lking_mvp_name_edt"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:hint="请输入账号"             android:textColor="@color/color_000000"             android:textSize="16sp" />     </LinearLayout>     <LinearLayout         android:layout_width="match_parent"         android:layout_height="45dp"         android:layout_margin="10dp">         <TextView             android:layout_width="wrap_content"             android:layout_height="match_parent"             android:gravity="center"             android:text="密    码:"             android:textColor="@color/color_000000"             android:textSize="18sp" />         <EditText             android:id="@+id/lking_mvp_pas_edt"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:hint="请输入密码"             android:textColor="@color/color_000000"             android:textSize="16sp" />     </LinearLayout>     <TextView         android:id="@+id/lking_mvp_login_txt"         android:layout_width="match_parent"         android:layout_height="45dp"         android:gravity="center"         android:text="登录"         android:textColor="@color/color_000000"         android:textSize="18sp" />     <ProgressBar         android:id="@+id/lking_mvp_login_pro"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:visibility="gone"         android:layout_marginTop="20dp" /> </LinearLayout>

3、继承接口进行数据显示

public class MvpActivity extends Activity implements ILoginView {     private EditText mNameEdt;     private EditText mPasswordEdt;     private TextView mLoginBtn;     private ProgressBar mLoading;     private LoginPresenter mLoginPresenter;     @Override     protected void onCreate(@Nullable Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_mvp);         initViews();     }

/**      * 初始化控件      */

    private void initViews() {         mNameEdt = (EditText) findViewById(R.id.lking_mvp_name_edt);         mPasswordEdt = (EditText) findViewById(R.id.lking_mvp_pas_edt);         mLoginBtn = (TextView) findViewById(R.id.lking_mvp_login_txt);         mLoading = (ProgressBar) findViewById(R.id.lking_mvp_login_pro);         mLoginPresenter = new LoginPresenter(this);         mLoginBtn.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 mLoginPresenter.login();             }         });     }     @Override     public String getName() {         return mNameEdt.getText().toString().trim();     }     @Override     public String getPassword() {         return mPasswordEdt.getText().toString().trim();     }     @Override     public void showLoading() {         mLoading.setVisibility(View.VISIBLE);     }     @Override     public void hideLoading() {         mLoading.setVisibility(View.GONE);     }     @Override     public void toMainActivity(LoginBean loginBean) {         Toast.makeText(this, "登录成功,跳转到主界面", Toast.LENGTH_SHORT).show();     }     @Override     public void showFailToast() {         Toast.makeText(this, "登录失败,请重新输入账号和密码", Toast.LENGTH_SHORT).show();         mNameEdt.setText("");         mPasswordEdt.setText("");     } }

主持人(Presenter

创建管理逻辑类

public class LoginPresenter {     private ILoginView mILoginView;     private LoginModel mLoginModel;     private Handler mHandler = new Handler();     public LoginPresenter(ILoginView iLoginView) {         mILoginView = iLoginView;         mLoginModel = new LoginModel();     }     public void login(){         mILoginView.showLoading();         mLoginModel.login(mILoginView.getName(), mILoginView.getPassword(), new ILoginModel.OnLoginListener() {             @Override             public void LoginSuccess(final LoginBean loginBean) {                 mHandler.post(new Runnable() {                     @Override                     public void run() {                         mILoginView.hideLoading();                         mILoginView.toMainActivity(loginBean);                     }                 });             }             @Override             public void LoginFail() {                 mHandler.post(new Runnable() {                     @Override                     public void run() {                         mILoginView.hideLoading();                         mILoginView.showFailToast();                     }                 });             }         });     } }

 

转载请注明原文地址: https://www.6miu.com/read-64670.html

最新回复(0)