MVP模式简介
简称:MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
模式特点
MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
MVP在Android中的应用
在Android项目中,V层对应于activity或者fragment,在整个模式中V层最薄,V层会实现一个接口,通过这个接口,回调P层传过来的数据,然后进行视图更新。
public class UserActivity extends BaseActivity<UserPresenter> implements UserView {
@Bind(R.id.tv_name)
TextView mTvName;
@Bind(R.id.tv_gender)
TextView mTvGender;
@Override
protected int onSetLayoutId() {
return R.layout.activity_main;
}
@Override
protected UserPresenter createPresenter() {
return new UserPresenter(mContext);
}
@Override
public void initView() {
//初始化一些UI
}
@Override
protected void initData() {
//请求用户数据
mPresenter.getUserData(1100);
}
/**
* 由MainPresenter回调过来的数据,然后更新UI
*
* @param userInfo
*/
@Override
public void setData(UserInfo userInfo) {
//更新UI
mTvName.setText(userInfo.getName());
mTvGender.setText(userInfo.getGender());
}
}
/**
* @作者: TJ
* @时间: 2018/7/23 16:56
* @描述: Activity基类,MVP中的V层,主要设置视图相关
*/
public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements View.OnClickListener, BaseView {
public final String TAG = this.getClass().getSimpleName();
protected BaseActivity mContext;
/**
* presenter
*/
protected P mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
//创建presenter并绑定view,这里默认创建一个Presenter,如果需要创建多个需要自己处理。
mPresenter = createPresenter();
if (mPresenter != null) mPresenter.attachView(this);
setContentView(onSetLayoutId());
init();
}
/**
* 设置布局文件
*
* @return 返回布局文件资源Id
*/
protected abstract int onSetLayoutId();
/**
* 创建Presenter
*
* @return 返回Presenter
*/
protected abstract P createPresenter();
/**
* 初始化页面
*/
protected void init() {
initView();
bindEvent();
initData();
}
/**
* 初始化view
*/
public abstract void initView();
/**
* 绑定事件
*/
public void bindEvent() {
}
/**
* 初始化数据
*/
protected void initData() {
}
@Override
public void onClick(View v) {
}
/**
* 显示一个Toast信息
*/
@Override
public void showToastMessage(String message) {
if (message != null) {
ToastUtils.showShort(message);
}
}
@Override
public void showToastMessage(int res) {
if (res != 0) {
ToastUtils.showShort(getString(res));
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
if (mPresenter != null) {
mPresenter.detachView();
mPresenter = null;
}
}
}
在V层创建一个Presenter,然后绑定View。在V层通过Presenter来调用Presenter中的一些方法,而在P层通过接口将数据回调给V层,这样实现了VP交互。
Android中P层为自定义的一个Presenter类,连接V层和M层,主要处理业务以及逻辑相关的东西。在Presenter会创建一个Modle类即M层,将数据传给传给M层进行网络请求、数据处理,然后通过接口将M层返回的数据传递给P层。
/**
* @作者: TJ
* @时间: 2018/8/2 16:53
* @描述: 用户相关业务以及逻辑,此类可以复用,只用于用户相关,可以扩充方法分别精选处理
*/
public class UserPresenter extends BasePresenter<UserView, UserModle> {
public UserPresenter(Context context) {
super(context);
}
@Override
protected UserModle createModel() {
return new UserModle();
}
/**
* 获取数据
*
* @param id
*/
public void getUserData(long id) {
mModel.getUserData(id, new LzyCallback<UserInfo>() {
@Override
public void onNext(UserInfo userInfo) {
mView.setData(userInfo);
}
});
}
}
/**
* @作者: TJ
* @时间: 2018/4/11 11:53
* @描述: Presenter基类,连接V层和M层,主要处理业务以及逻辑相关的东西,将相关数据传给M层进行网络请求、数据处理,然后将M层返回的数据传递给P层
*/
public abstract class BasePresenter<V extends BaseView, M extends BaseModel> {
public final String TAG = this.getClass().getSimpleName();
protected V mView;
protected M mModel;
protected Context mContext;
public BasePresenter(Context context) {
mContext = context;
}
public void attachView(V view) {
mView = view;
mModel = createModel();
onViewAttach();
}
/**
* 将Presenter与View解除 Presenter与Model解除
*/
public void detachView() {
mView = null;
mModel = null;
onViewDetach();
}
/**
* 当View与Presenter绑定时回调,此时界面控件等均未初始化
*/
protected void onViewAttach() {
}
/**
* 当View与Presenter解除绑定时回调
*/
protected void onViewDetach() {
}
/**
* 创建model
*
* @return
*/
protected abstract M createModel();
}
Android中M层为自定义的Model类,以及服务器返回的数据类,主要获取数据以及处理数据,然后返回给P层。该类在Presenter中创建,直接调用Model中的方法,通过接口将数据返回给Presenter。
/**
* @作者: TJ
* @时间: 2018/8/2 16:49
* @描述: 从Presenter传过来数据,然后进行网络请求以及对请求的数据处理等,此类可以复用,只要有相同的请求都可以复用
*/
public class UserModle extends BaseModel {
public void getUserData(long id, LzyCallback<UserInfo> callback) {
// Observable<HttpResult<List<UserInfo>>> observable = mApiService.getUserInfo(id);
// applySchedulers(observable);
// observable.subscribe(this.<HttpResult<List<UserInfo>>>newObserver(callback));
//简化一下
applySchedulers(mApiService.getUserInfo(id)).subscribe(newObserver(callback));
}
}
/**
* @作者: TJ
* @时间: 2018/7/24 9:26
* @描述: Model基类,MVP中M层,对应P层,主要获取数据以及处理数据,然后返回给P层
*/
public class BaseModel {
public final String TAG = this.getClass().getSimpleName();
protected CompositeDisposable mCompositeDisposable;
protected final RetrofitApiService mApiService;
public BaseModel() {
//Presenter在创建Model对象的时候创建CompositeDisposable对象,在Presenter解除与View绑定的时候,取消所有的订阅。
mCompositeDisposable = new CompositeDisposable();
//初始化retrofit,给之后的网络请求做准备
mApiService = RetrofitApi.getService();
}
//将每次的订阅操作进行封装,简化重复代码量,分割返回的数据
public <T> Observable<T> applySchedulers(Observable<HttpResult<T>> o) {
Observable<T> observable = o.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<HttpResult<T>, T>() {
@Override
public T apply(HttpResult<T> result) throws Exception {
return result.getData();
}
});
return observable;
}
/**
* 创建观察者 这里对观察着过滤一次,过滤出我们想要的信息,错误的信息toast
*
* @param <T>
* @return
*/
public <T> Observer<T> newObserver(final LzyCallback callback) {
return new Observer<T>() {
@Override
public void onError(Throwable e) {
LogUtils.e(TAG, "newObserver-> onError: ---" + e.getMessage());
callback.onError(e);
}
@Override
public void onComplete() {
LogUtils.e(TAG, "newObserver-> onComplete: ---");
callback.onComplete();
}
@Override
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onNext(T t) {
if (!mCompositeDisposable.isDisposed()) {
LogUtils.e(TAG, "newObserver-> onNext: ---");
callback.onNext(t);
}
}
};
}
}