经过上一篇博客的介绍 带你一步一步认识MVP -step2
接下来我们就来解决上一篇博客遇到的问题
首先还是先来我们的base类
我们来看basemodel类这个类就是个空壳没什么逻辑处理
/**
* Created by PC-304 on 2018/5/8.
* model的base类
*/
public class BaseModel {
}
接下来是baseView类跟以前一样
public interface BaseView {
}
下面是我们的basepresenter类跟以前不太一样了
/**
* Created by PC-304 on 2018/5/8.
* Presenter的Base类
*/
public class BasePresenter<V extends BaseView, M extends BaseModel> {
private WeakReference<V> mView;
private M mModel; // 动态创建的 model 的对象
@SuppressWarnings("unchecked")
public void attach(WeakReference<V> mView) {
this.mView = mView;
// 最好要判断一下类型
Type[] params = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments();
try {
mModel = (M) ((Class) params[1]).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//内存泄漏解决
public void detach() {
if (mView == null) return;
this.mView.clear();
this.mView = null;
}
//获取view对象
public V getView() {
if (mView == null) return null;
return mView.get();
}
//获取model对象
public M getModel() {
return mModel;
}
}
这里我们的prestnter持有了model的对象并在attach处理中给其初始化这里还需要注意的是我们的view已经不再是之前的view了而是添加WeakReference的view这样的话在activity销毁的时候我们的view得以正常销毁了。
在下面是我们的activity的处理
public abstract class BaseMvpActivity<P extends BasePresenter> extends AppCompatActivity implements BaseView {
private P mPresenter;
@SuppressWarnings("unchecked")
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView();
// 创建 P,创建只能交给 子类,每个 Activity 都不一样
mPresenter = createPresenter();
if (mPresenter != null) {//天价处理可能在使用过程中不适用MVP
mPresenter.attach(new WeakReference(this));
}
initView();
initData();
}
// 由子类去实现创建
protected abstract P createPresenter();
protected abstract void initData();
protected abstract void initView();
//或者实现給view的id调用setContentView方法
protected abstract void setContentView();
@Override
public void onDestroy() {
super.onDestroy();
if (mPresenter==null) return;
mPresenter.detach();
}
public P getPresenter() {
return mPresenter;
}
}
跟前面的处理几乎一致唯一不同的在下面(如果不使用mvp这里也不会报错了)
if (mPresenter != null) {//天价处理可能在使用过程中不适用MVP
mPresenter.attach(new WeakReference(this));
}
最后就是基于这些基类的处理了
首先还是model类
public class UserInfoModel extends BaseModel{
public List<UserInfo> getUserInfo() {
List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(new UserInfo("a", "1"));
userInfos.add(new UserInfo("b", "2"));
userInfos.add(new UserInfo("c", "3"));
return userInfos;
}
}
之后是view类
public interface UserInfoView extends BaseView {
void onLoading(); // 1.正在加载中
void onError(); // 2.获取出错了
void onSucceed(List<UserInfo> userInfo); // 3.成功了要显示数据
}
然后是presenter类
/**
* Created by PC-304 on 2018/5/8.
* MVP 进阶
* 好处 1.在activity销毁的时候 detach防治调用报空指针等错误 相比最初的更安全些
* 解决 1. 很多代码是公用反复的,attach detach 每个 Presenter 都要有
* 2. Activity -> View 的 attach detach 每个 View 层也要有
* 问题 1.内存泄漏风险 解决
* 2.model初始化不够简单 解决
*/
public class UserInfoPresenter extends BasePresenter<UserInfoView, UserInfoModel> {
public void getDate() {
try {
List<UserInfo> userInfos = getModel().getUserInfo();
if (getView() == null) return;
getView().onSucceed(userInfos);
} catch (Exception e) {
getView().onError();
}
}
}
最后是我们的activity的调用
public class MainActivity extends BaseMvpActivity<UserInfoPresenter> implements UserInfoView {
@Override
protected UserInfoPresenter createPresenter() {
return new UserInfoPresenter();
}
@Override
protected void initData() {
getPresenter().getDate();
}
@Override
protected void initView() {
setContentView(R.layout.activity_main);
}
@Override
protected void setContentView() {
}
@Override
public void onLoading() {
}
@Override
public void onError() {
//todo 错误提示
}
@Override
public void onSucceed(List<UserInfo> userInfo) {
//todo 显示数据列表
int count = userInfo.size();
}
}
是不是很简单,希望这些能帮助到你们。