天天看点

Android架构模式笔记2——MVP

前言

在Android开发中除了MVC,我们还会用到MVP。下面分享一下我对MVP架构模式的理解。

MVP详解

MVP全称是Model View Presenter。

  • M:业务模型;
  • V:用户界面;
  • P:主持者,Model和View之间的桥梁。
    Android架构模式笔记2——MVP

MVP核心思想

把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model类。

MVP的作用

  1. 分离视图逻辑和业务逻辑,降低耦合;
  2. Activity只处理生命周期的任务,代码简洁;
  3. 视图逻辑和业务逻辑抽象到了View和Presenter中,提高阅读性;
  4. Presenter被抽象成接口,可以有多种具体的实现;
  5. 业务逻辑在Presenter中,避免后台线程引用Activity导致内存泄漏;

MVP实现登录小案例

1.分包结构

Android架构模式笔记2——MVP

2.配置Model的build.gradle文件

这个是个人习惯,我一般是使用小刀注解和支持Java8。

android{
    // 使用Java8
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
}
dependencies{
    implementation 'com.jakewharton:butterknife:8.7.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0'
}
           

3.xml文件

界面布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".view.MainActivity"
    tools:layout_editor_absoluteY="81dp">

    <EditText
        android:id="@+id/et_username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="用户名"
        app:layout_constraintBottom_toTopOf="@+id/et_pwd"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <EditText
        android:id="@+id/et_pwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码"
        app:layout_constraintTop_toBottomOf="@+id/et_username" />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"
        app:layout_constraintTop_toBottomOf="@+id/et_pwd" />
</android.support.constraint.ConstraintLayout>
           

4.Model层

主要是Bean数据类

public class User {
    /**
     * 用户名
     */
    private String name;
    /**
     * 密码
     */
    private String pwd;

    public User(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
           

5.Presenter层

主持者,Model和View之间的桥梁。在实际开发当中是写一个BasePresenter接口,其他接口继承它拓展其他方法;登录小案例只做简单的处理。

public interface BasePresenter {

    /**
     * 绑定视图
     *
     * @param v 视图
     */
    void attachView(BaseView v);

    /**
     * 截图视图绑定
     */
    void detachView();
    
    /**
     * 登录的方法
     */
    void login(User user);
}
           

主页界面的主持者实现主持者接口,在这个类里面进行业务逻辑的处理和实现。

public class MainPresenterImp implements BasePresenter  {

    private BaseView baseView;

    @Override
    public void attachView(BaseView v) {
        this.baseView = v;
    }

    @Override
    public void detachView() {
        baseView = null;
    }

    @Override
    public void login(User user) {
        if (!TextUtils.isEmpty(user.getName()) && !TextUtils.isEmpty(user.getPwd())) {
            if (user.getName().equals("zhangsan") && user.getPwd().equals("123456")){
                baseView.showToast("登录成功");
            }else {
                baseView.showToast("登录失败");
            }
        } else {
            baseView.showToast("用户名或密码不能为空!!!");
        }
    }
}
           

6.View层

BaseView在实际开发中是一个所有View接口的父类,登录小案例只做简单的处理。

public interface BaseView {

    /**
     * Toast显示方法
     *
     * @param msg Toast显示的内容
     */
    void showToast(String msg);

    /**
     * 登录成功的方法
     * @param msg 显示的信息
     */
    void loginSuccess(String msg);

    /**
     * 登录失败的方法
     * @param msg 显示的信息
     */
    void loginFailed(String msg);
}
           

MainActivity实现BaseView接口里面的方法

public class MainActivity extends AppCompatActivity implements BaseView{

    @BindView(R.id.et_username)
    EditText etUsername;
    @BindView(R.id.et_pwd)
    EditText etPwd;

    private MainPresenterImp mainPresenterImp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mainPresenterImp = new MainPresenterImp();
        mainPresenterImp.attachView(this);
    }

    @OnClick(R.id.btn_login)
    public void onViewClicked() {
        User user = new User(etUsername.getText().toString(),etPwd.getText().toString());
        mainPresenterImp.login(user);
    }

    @Override
    public void showToast(String msg) {
        Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void loginSuccess(String msg) {
        showToast(msg);
    }

    @Override
    public void loginFailed(String msg) {
        showToast(msg);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mainPresenterImp.detachView();
    }
}
           
上面内容是我对MVP架构模式的一些理解,通过MVP来实现登录小案例,希望对想要了解MVP的小伙伴们有帮助。