天天看點

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的小夥伴們有幫助。