欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MVP框架学习笔记

程序员文章站 2022-04-05 17:10:21
...

一.什么是MVP框架
MVP的思想是将activity作为view层,只负责与XML的渲染和监听事件,具体处理数据逻辑放到一个新定义的Present层。减少了activity负责的事情。并且可以强迫开发者养成分模块功能开发的思想。开发前设计好功能模块,而不是像以前一样写流水账一样写代码。从头写到尾。可以更好的降低软件的耦合性,方便代码的复用和工程开发。

(1)Presenter – 交互中间人:Presenter主要作为沟通View与Model的桥梁,它从Model层检索数据后,返回给View层,使得View与Model之间没有耦合,也将业务逻辑从View角色上抽离出来。
(2)View – 用户界面:View通常是指Activity、Fragment或者某个View控件,它含有一个Presenter成员变量。通常View需要实现一个逻辑接口,将View上的操作转交给Presenter进行实现,最后,Presenter 调用View逻辑接口将结果返回给View元素。
(3)Model – 数据的存取:Model 角色主要是提供数据的存取功能。Presenter 需要通过Model层存储、获取数据,Model就像一个数据仓库。更直白的说,Model是封装了数据库DAO或者网络获取数据的角色,或者两种数据方式获取的集合。
MVP框架学习笔记

二.MVP框架理解
我们在日常开发中,很多网络请求是重复的,比如加入购物车,这个接口会在商品详情中出现,也可能会在商品列表中出现, 在购物车的数量更改上也可能用到它,如果不复用他,我们就需要在每个界面的model层中去复制粘贴他,但是这样又远离的mvp的中心思想,mvp就是想让你在最大程度上复用,减少无用代码,那么这样的接口我们应该怎样处理呢。对于这个问题有以下几个思路解决:
1.我们可以让一个p层去持有多个model,通过这样的方式来复用model;
2.我们可以让一个view持有多个p,每个p去调用不同的model分别处理不同的事务;
3. 我们可以将model模块进行拆分,将大量复用的model单独拆分出来,让这个model可以去被其他model调用,这样也实现了最大程度上的复用;
三.MVP框架存在的问题
尽管已经有了大量的应用,但不可否认该模式的还是存在一些问题,这些问题在携程的使用过程中也得到了体现。比如,上下文丢失问题,生命周期问题,内存泄露问题以及大量的自定义接口,回调链变长等问题。可以归纳为:
1.业务复杂时,可能使得Activity变成更加复杂,比如要实现N个IView,然后写更多个模版方法。
2.业务复杂时,各个角色之间通信会变得很冗长和复杂,回调链过长。
3.Presenter处理业务,让业务变得很分散,不能全局掌握业务,很难去回答某个业务究竟是在哪里处理的。
4.用Presenter替代Controller是一个危险的做法,可能出现内存泄漏,生命周期不同步,上下文丢失等问题。
四.MVP框架实例参照
项目目录:
MVP框架学习笔记
LoginBean文件:
package com.mvptest.mvp_demo.bean;

/**
* Author:XuPF
* Time:2018/8/14 14:36
* Description:This is LoginBean
*/
public class LoginBean {

private String userName;
private String userPwd;

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getUserPwd() {
    return userPwd;
}

public void setUserPwd(String userPwd) {
    this.userPwd = userPwd;
}

public LoginBean(String userName, String userPwd) {
    this.userName = userName;
    this.userPwd = userPwd;
}

}

LoginModel文件:
package com.mvptest.mvp_demo.model;

import android.text.TextUtils;

import com.mvptest.mvp_demo.bean.LoginBean;
import com.mvptest.mvp_demo.netWork.NetTask;
import com.mvptest.mvp_demo.netWork.RequestStatus;

/**
* Author:XuPF
* Time:2018/8/14 14:53
* Description:This is LoginModel
*/
public class LoginModel implements NetTask {
@Override
public void exec(LoginBean loginBean, RequestStatus requestStatus) {
String name = loginBean.getUserName();
String pwd = loginBean.getUserPwd();
if (name == null && TextUtils.isEmpty(name)) {
requestStatus.onError();
return;
}
if (pwd == null && TextUtils.isEmpty(pwd)) {
requestStatus.onError();
return;
}

    //这里处理和网络交互的逻辑
    requestStatus.onStart();
    //模拟请求网络

    if (!name.equals("1")) {
        requestStatus.onError();
        return;
    } else {
        if (!pwd.equals("1")) {
            requestStatus.onError();
            return;
        } else {
            requestStatus.onSuccess("恭喜你登录成功");
        }
    }
}

}
LoginPresenter文件:
package com.mvptest.mvp_demo.presenter;

import com.mvptest.mvp_demo.view.LoginBaseInterface;
import com.mvptest.mvp_demo.bean.LoginBean;
import com.mvptest.mvp_demo.netWork.NetTask;
import com.mvptest.mvp_demo.netWork.RequestStatus;

/**
* Author:XuPF
* Time:2018/8/14 14:48
* Description:This is LoginPresenter
* LoginPresenter 实现约定接口中的presenter接口和请求网络状态的接口
*/
public class LoginPresenter implements LoginBaseInterface.LoginPresenterInterface,RequestStatus {

private NetTask<LoginBean> netTask;
private LoginBaseInterface.LoginViewInterface viewInterface;

public LoginPresenter(NetTask<LoginBean> netTask, LoginBaseInterface.LoginViewInterface viewInterface) {
    this.netTask = netTask;
    this.viewInterface = viewInterface;
}

@Override
public void requestToLogin(LoginBean loginBean) {
    netTask.exec(loginBean,this);
}

@Override
public void onStart() {
    viewInterface.showRequestNetDialog();
}

@Override
public void onSuccess(String str) {
    viewInterface.cancelRequestNetDialog();
    viewInterface.LoginSuccess(str);
}

@Override
public void onError() {
    viewInterface.cancelRequestNetDialog();
    viewInterface.LoginUnSuccess();
}

}
LoginActivity文件:

package com.mvptest.mvp_demo.view;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.mvptest.mvp_demo.R;
import com.mvptest.mvp_demo.bean.LoginBean;
import com.mvptest.mvp_demo.model.LoginModel;
import com.mvptest.mvp_demo.presenter.LoginPresenter;

public class LoginActivity extends AppCompatActivity implements LoginBaseInterface.LoginViewInterface, View.OnClickListener {

private ProgressBar mLoginPb;
/**
 * 手机号
 */
private EditText mUserMobileEt;
/**
 * 密码
 */
private EditText mUserPwdEt;
/**
 * 登 录
 */
private TextView mLoginConfirmTv;
private LoginPresenter loginPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    initView();
    LoginModel loginModel = new LoginModel();
    loginPresenter = new LoginPresenter(loginModel,this);

}

@Override
public void showRequestNetDialog() {
    if (!mLoginPb.isShown()) {
        mLoginPb.setVisibility(View.VISIBLE);
    }

}

@Override
public void cancelRequestNetDialog() {
    if (mLoginPb.isShown()) {
        mLoginPb.setVisibility(View.INVISIBLE);
    }
}

@Override
public void LoginSuccess(Object o) {
    if (mLoginPb.isShown()) {
        mLoginPb.setVisibility(View.INVISIBLE);
    }
    Toast.makeText(getApplicationContext(), (String)o, Toast.LENGTH_LONG).show();
    Intent intent = new Intent(LoginActivity.this,FirstActivity.class);
    startActivity(intent);
}


@Override
public void LoginUnSuccess() {
    if (mLoginPb.isShown()) {
        mLoginPb.setVisibility(View.INVISIBLE);
    }
    Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_LONG).show();
}

private void initView() {
    mLoginPb = (ProgressBar) findViewById(R.id.login_pb);
    mUserMobileEt = (EditText) findViewById(R.id.user_mobile_et);
    mUserPwdEt = (EditText) findViewById(R.id.user_pwd_et);
    mLoginConfirmTv = (TextView) findViewById(R.id.login_confirm_tv);
    mLoginConfirmTv.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        default:
            break;
        case R.id.login_confirm_tv:
            loginPresenter.requestToLogin(new LoginBean(mUserMobileEt.getText().toString().trim(),mUserPwdEt.getText().toString().trim()));

            break;
    }

}

}
LoginBaseInterface文件:

package com.mvptest.mvp_demo.view;

/**
* Author:XuPF
* Time:2018/8/14 14:38
* Description:This is LoginBaseInterface
*/
public class LoginBaseInterface {

public interface LoginPresenterInterface<T>{

    void requestToLogin(T t);
}

public interface LoginViewInterface<T>{

    void showRequestNetDialog();//展示请求网络的dialog
    void cancelRequestNetDialog();//finish掉dialog

    void LoginSuccess(T t);//登录成功
    void LoginUnSuccess();//登录不成功
}

}
FirstActivity文件:
package com.mvptest.mvp_demo.view;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import com.mvptest.mvp_demo.R;
import com.mvptest.mvp_demo.model.LoginModel;
import com.mvptest.mvp_demo.presenter.LoginPresenter;

public class FirstActivity extends AppCompatActivity implements LoginBaseInterface.LoginViewInterface, View.OnClickListener {
private TextView mFirstView;
@Override
public void onClick(View view) {

}

@Override
public void showRequestNetDialog() {

}

@Override
public void cancelRequestNetDialog() {

}

@Override
public void LoginSuccess(Object o) {

}

@Override
public void LoginUnSuccess() {

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

}
private void initView(){
    mFirstView = (TextView) findViewById(R.id.FirstView);
}

}

相关标签: MVP