MVP(Model-View-Presenter)模式:
- Model: 数据层. 负责与网络层和数据库层的逻辑交互.
- View: UI层. 显示数据, 并向Presenter报告用户行为.
- Presenter: 从Model拿数据, 应用到UI层, 管理UI的状态, 决定要显示什么, 响应用户的行为.
MVP 模式
登录的栗子:
在此栗子中
M :对应的是LoginModel ,实现了Model中接口中的 login(String username, String password) 方法,将username、password放在联网请求中,进行请求服务器。
V : 对应的是LoginActivity, 继承了封装的activity基类,实现 MainContract.View中的方法 ,在实现的方法中,进行进度条加载、和登陆成功or失败的UI的展示:
public class LoginActivity extends BaseMvpActivity<LoginPresenter> implements MainContract.View {
@BindView(R.id.et_username_login)
TextInputEditText etUsernameLogin;
@BindView(R.id.et_password_login)
TextInputEditText etPasswordLogin;
@Override
public int getLayoutId() {
return R.layout.activity_main;
}
@Override
public void initView() {
mPresenter = new LoginPresenter();
mPresenter.attachView(this);
}
/**
* @return 帐号
*/
private String getUsername() {
return etUsernameLogin.getText().toString().trim();
}
/**
* @return 密码
*/
private String getPassword() {
return etPasswordLogin.getText().toString().trim();
}
@Override
public void onSuccess(BaseObjectBean bean) {
Toast.makeText(this, bean.getErrorMsg(), Toast.LENGTH_SHORT).show();
}
@Override
public void showLoading() {
ProgressDialog.getInstance().show(this);
}
@Override
public void hideLoading() {
ProgressDialog.getInstance().dismiss();
}
@Override
public void onError(Throwable throwable) {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
}
@OnClick(R.id.btn_signin_login)
public void onViewClicked() {
if (getUsername().isEmpty() || getPassword().isEmpty()) {
Toast.makeText(this, "帐号密码不能为空", Toast.LENGTH_SHORT).show();
return;
}
mPresenter.login(getUsername(), getPassword());
}
}
P: 对应的是LoginPresenter,继承了自定义Presenter基类,实现MainContract.Presenter 接口中的 login(String username, String password) 方法实例化Model,在MainPresenter login(String username, String password)方法中,调用model的网络请求,将username、password放在model的login()方法中,进行请求服务器。
请求服务器前 使用MainContract.View中的 mView.showLoading()方法,进行显示加载中;在成功失败的回调中,使用对应的方法,以及取消加载。
public class LoginPresenter extends BasePresenter<MainContract.View> implements MainContract.Presenter {
private MainContract.Model model;
public LoginPresenter() {
model = new LoginModel();
}
@Override
public void login(String username, String password) {
//View是否绑定 如果没有绑定,就不执行网络请求
if (!isViewAttached()) {
return;
}
mView.showLoading();
model.login(username, password)
.compose(RxScheduler.<BaseObjectBean<LoginBean>>Flo_io_main())
.as(mView.<BaseObjectBean<LoginBean>>bindAutoDispose())
.subscribe(new Consumer<BaseObjectBean<LoginBean>>() {
@Override
public void accept(BaseObjectBean<LoginBean> bean) throws Exception {
mView.onSuccess(bean);
mView.hideLoading();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
mView.onError(throwable);
mView.hideLoading();
}
});
}
}
Model,View,Presenter接口统一由 MainContract来管理
public interface MainContract {
interface Model {
Flowable<BaseObjectBean<LoginBean>> login(String username, String password);
}
interface View extends BaseView {
@Override
void showLoading();
@Override
void hideLoading();
@Override
void onError(Throwable throwable);
void onSuccess(BaseObjectBean<LoginBean> bean);
}
interface Presenter {
/**
* 登陆
*
* @param username
* @param password
*/
void login(String username, String password);
}
各个封装基类如下:
BasePresenter 类,
public class BasePresenter<V extends BaseView> {
protected V mView;
/**
* 绑定view,一般在初始化中调用该方法
*
* @param view view
*/
public void attachView(V view) {
this.mView = view;
}
/**
* 解除绑定view,一般在onDestroy中调用
*/
public void detachView() {
this.mView = null;
}
/**
* View是否绑定
*
* @return
*/
public boolean isViewAttached() {
return mView != null;
}
}
BaseVIew 类
public interface BaseView {
/**
* 显示加载中
*/
void showLoading();
/**
* 隐藏加载
*/
void hideLoading();
/**
* 数据获取失败
* @param throwable
*/
void onError(Throwable throwable);
/**
* 绑定Android生命周期 防止RxJava内存泄漏
*
* @param <T>
* @return
*/
<T> AutoDisposeConverter<T> bindAutoDispose();
}
BaseMvpActivity 类
public abstract class BaseMvpActivity<T extends BasePresenter> extends BaseActivity implements BaseView {
protected T mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
if (mPresenter != null) {
mPresenter.detachView();
}
super.onDestroy();
}
/**
* 绑定生命周期 防止MVP内存泄漏
*
* @param <T>
* @return
*/
@Override
public <T> AutoDisposeConverter<T> bindAutoDispose() {
return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider
.from(this, Lifecycle.Event.ON_DESTROY));
}
}
总结: 实现步骤(以登录为例子)
1.创建登录Contract: LoginContract, 用于统一管理mvp接口
2.创建mvp类并实现上面创建的接口
public class LoginActivity extends BaseMvpActivity<LoginPresenter> implements MainContract.View
public class LoginModel implements MainContract.Model
public class LoginPresenter extends BasePresenter<MainContract.View> implements MainContract.Presenter