关于MVP的相关文章网上已经多如牛毛,在此不做过多的介绍。这里主要是记载下自己在项目中使用MVP的一点点总结。
0x00:BaseView和BasePresenter
BaseView和BasePresenter主要是两个接口,接口定义如下:
BaseView
/**
* BaseView接口
*/
public interface BaseView {
void showErrorMsg(String msg);
//======= State =======
//展示异常提示
void stateError();
//数据为空时展示
void stateEmpty();
//加载中
void stateLoading();
//展示页面,取消加载等状态时使用
void stateMain();
}
BasePresenter
/**
* BasePresenter接口
* 该接口将提供泛型
*/
public interface BasePresenter<T extends BaseView>{
// 绑定View
void attachView(T view);
// 解绑View
void detachView();
}
BasePresenter接口中值得注意的是接口上的泛型。
接下来就是两个实现接口的实现类
0x01:BaseActivity和CommonPresenter
BaseActivity和CommonPresenter各自实现于BaseView和BasePresenter
代码如下:
BaseActivity
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity implements BaseView {
protected T mPresenter;
@Override
public void showErrorMsg(String msg) {
// Empty
}
@Override
public void stateError() {
// Empty
}
@Override
public void stateEmpty() {
// Empty
}
@Override
public void stateLoading() {
// Empty
}
@Override
public void stateMain() {
// Empty
}
// 这里的抽象方法作为一个示例,大家可以自行添加需要的抽象方法
protected abstract void initData();
}
CommonPresenter
/**
* 通用Presenter封装
*/
public class CommonPresenter<T extends BaseView> implements BasePresenter<T> {
// 绑定的View
protected T mView;
@Override
public void attachView(T view) {
this.mView = view;
}
@Override
public void detachView() {
this.mView = null;
}
}
在这里需要注意的是
CommonPresenter<T extends BaseView> implements BasePresenter<T>
根据上面的接口可以清楚的知道BasePresenter的泛型结构
public interface BasePresenter<T extends BaseView>
那么这里就牵扯到带有泛型的类的继承,带有泛型的类的继承就如上面两句代码。
直接将T extends BaseView移到子类的泛型中。
0x02:Model类
public class TestModel {
private String name;
private int age;
public TestModel(String name, int age) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
0x03:contract包和XXXContract接口
在这里我借鉴了google官方的MVP构架,暂时称其为”契约接口”
思路是通过”契约接口”将UI操作和数据业务逻辑操作抽象出来。代码如下:
public interface DailyPatrolContract {
// UI操作接口
interface View extends BaseView{
// 展示数据,显示到UI上
void showData(TestModel model);
}
// 数据业务逻辑接口
interface Presenter extends BasePresenter<View>{
// 加载数据
void loadData();
}
}
通过上述的”契约接口”可以非常清晰的展示UI操作和数据业务操作。
0x04:完成构架
下面使用TestActivity和TestPresenter两个类展示最终使用
TestPresenter:
public class TestPresenter extends CommonPresenter<DailyPatrolContract.View> implements DailyPatrolContract.Presenter{
public TestPresenter(){
}
@Override
public void loadData{
// 数据业务操作,假定数据已经成功获取
TestModel model = new TestModle("xiaoming", 23);
//数据业务操作完成调用UI展示
mView.showData(model);
}
}
TestActivity
public class TestActivityextends BaseActivity<TestPresenter> implements DailyPatrolContract.View{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化TestPresenter类
mView = TestPresenter();
mView.attachView(this);
/**
* loadData可能是耗时工作,不能放到UI线程中。
* 这里主要演示如何构架
*/
mView.loadData();
}
@Override
public void showData(TestModel model){
// 展示UI
}
@Override
protected void onDestroy() {
super.onDestroy();
mView.detachView();
}
}
以上是最简单的MVP模型。这个简单的MVP模型也存在一些不足,比如TestPresenter类实例化的时候都要在UI层面初始化。后续我将使用Dragger2注入技术解决这个问题
参考文章:
MVP google官方demo比较分析