MVP框架学习笔记

一.什么是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框架理解
我们在日常开发中,很多网络请求是重复的,比如加入购物车,这个接口会在商品详情中出现,也可能会在商品列表中出现, 在购物车的数量更改上也可能用到它,如果不复用他,我们就需要在每个界面的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框架实例参照
项目目录:
这里写图片描述
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);
}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值