本文将记录自己项目中用到的MVP框架模板,方便同学参考。对于MVP框架不熟的同学,建议看下这篇文章:选择恐惧症的福音!教你认清MVC,MVP和MVVM
下面看下我项目中的流程图:
这样看可能并不是很清晰,大概思路就是V调用P中的请求,P调用M的请求,M请求成功后回调P,P再回调V,最后获取数据显示。
下面教大家一步一步来实现这个模板,先看下模块UML图:
咋一看好复杂。可能我UML图画的不好的原因吧。
首先定义BaseView接口
public interface BaseView<T> {
void setData(List<T> datas);
void hideProgress();
void showProgress();
interface StudentListView extends BaseView<Student> {
}
}
其中StudentListView是业务接口,继承BaseView接口,Student是业务类,如果要扩展业务接口,可以继续在这个文件添加。
接着定义BasePresenter接口
public interface BasePresenter {
interface StudentListPresenter extends BasePresenter {
void requestNetWork(int id);
}
}
同样这里定义了P层的基本接口和业务接口,可以继承在这里扩展。
接着定义BasePresenterImpl抽象类
public abstract class BasePresenterImpl<T> {
protected Reference<T> mViewRef;
public void attachView(T view) {
mViewRef = new WeakReference<T>(view);
}
protected T getView() {
return mViewRef.get();
}
public boolean isViewAttached() {
return mViewRef != null && mViewRef.get() != null;
}
public void detachView() {
if (mViewRef != null) {
mViewRef.clear();
mViewRef = null;
}
}
}
可以看到该抽象类里面依赖了一个V,同时将V的初始化和销毁放在这个基础类里面。
接着再定义BaseDataBridge接口
public interface BaseDataBridge<T> {
void addData(List<T> datas);
void error();
interface StudentListData extends BaseDataBridge<Student> {
}
}
这是什么鬼?要它有何用啊?看命名就知道它是一个桥接接口,用于P和M之间进行回调。里面可以扩展不同业务的桥接接口。
下面定义一个业务类P的实现:
public class StudentListPresenterImpl extends BasePresenterImpl<BaseView.StudentListView>
implements BasePresenter.StudentListPresenter, BaseDataBridge.StudentListData {
private BaseModel.StudentListModel studentListModel;
public StudentListPresenterImpl() {
studentListModel = new StudentListModelImpl();
}
@Override
public void requestNetWork(int id) {
studentListModel.requestStudentList(id, this);
}
@Override
public void addData(List<Student> datas) {
getView().setData(datas);
}
@Override
public void error() {
}
}
可以看到它继承基础类,实现业务P接口和业务桥接接口。同样我们看到了里面组合了M层的业务对象(BaseModel.StudentListModel)。
这个业务P类是该业务的中心类,它里面既依赖V,又组合M,又实现业务接口和桥接接口。起到了承上启下的作用。
下面看下BaseModel接口实现:
public interface BaseModel<T> {
void netWork(T model);
interface StudentListModel extends BaseModel<BaseDataBridge.StudentListData> {
void requestStudentList(int id, BaseDataBridge.StudentListData studentListData);
}
}
里面同样是M层的业务接口。业务接口里面依赖业务桥接接口,这样的话,M层取得数据之后,可以通过桥接接口回调到P层。
下面举例业务M的实现类:
public class StudentListModelImpl implements BaseModel.StudentListModel {
Handler handler = new Handler(Looper.getMainLooper());
@Override
public void netWork(final BaseDataBridge.StudentListData model) {
}
@Override
public void requestStudentList(int id, final BaseDataBridge.StudentListData studentListData) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
final List<Student> data = new ArrayList<Student>();
data.add(new Student("wuliqing"));
handler.post(new Runnable() {
@Override
public void run() {
studentListData.addData(data);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
该业务实现类里面只是模拟了加载耗时操作并切换到主线程做数据回调。实际应用当中肯定不能这样写,推荐用RXJAVA来实现。
举个我项目中的实现:
public class ImageListModelImpl implements BaseModel.ImageListModel {
@Override
public void netWorkList(int id, final int page, final BaseDataBridge.ImageListData imageListData) {
NetWorkRequest.imageList(id, page, new MySubscriber<BaseBean.ImageListBean>() {
@Override
public void onError(Throwable e) {
imageListData.error();
}
@SuppressWarnings("unchecked")
@Override
public void onNext(BaseBean.ImageListBean imageListBean) {
imageListData.addData(imageListBean.getInfo());
}
});
}
}
可以清晰的看到在onNext中做了数据回调。
最后来封装下MvpActivity:
public abstract class MvpActivity<V, T extends BasePresenterImpl<V>> extends AppCompatActivity {
protected T mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter = createPresenter();
mPresenter.attachView((V) this);
setContentView(getLayoutId());
initData();
}
protected void initData() {
}
protected abstract T createPresenter();
protected abstract int getLayoutId();
@Override
protected void onDestroy() {
super.onDestroy();
mPresenter.detachView();
}
}
可以看到基本就是采用模版方法模式+泛型来做封装。
子类只要继承它,传递业务类和实现相关函数即可。
举例如下:
public class MainActivity extends MvpActivity<BaseView.StudentListView, StudentListPresenterImpl>
implements BaseView.StudentListView {
@Override
protected StudentListPresenterImpl createPresenter() {
return new StudentListPresenterImpl();
}
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initData() {
mPresenter.requestNetWork(1);
}
@Override
public void setData(List<Student> datas) {
Toast.makeText(this, "datas = " + datas.toString(), Toast.LENGTH_SHORT).show();
}
@Override
public void hideProgress() {
}
@Override
public void showProgress() {
}
}
可以看到我们的Activity很简单,业务流程都交给了P,P又交给M。实现了V和M之间的完全解耦。
好的模板框架给大家分享,希望能帮到大家。