带你一步一步认识MVP -step3

经过上一篇博客的介绍 带你一步一步认识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();
    }

}

是不是很简单,希望这些能帮助到你们。

猜你喜欢

转载自blog.csdn.net/u011048906/article/details/80252764