MVP项目架构 - 让你的Activity腰围瘦下来

本章节 我门将运用上一讲Retrofit + RxJava + OkHttp 的简单封装的网络请求框架

前言

最开始我学习android的时候只会用MVC,MVC相信大家都知道,缺点很明显,代码结构很乱,开发玩一个功能,几个月后再回来要改什么功能,一看代码.我**X******这TM是谁写的代码(明明就是自己写的),纠其原因就是因为Activity中同时拥有业务和UI逻辑代码,不排除还可能存在某些不良编程习惯导致。

那么什么是MVP架构?

MVP代表Model,View和Presenter。
View层负责处理用户事件和视图部分的展示。在Android中,它可能是Activity或者Fragment类。
Model层负责访问数据。数据可以是远端的Server API,本地数据库或者SharedPreference等。
Presenter层是连接(或适配)View和Model的桥梁。

这么说可能不太好理解 我们看图说话....(为了使你更好理解 图片上已经备注好了顺序和过程)


MVP项目架构 - 让你的Activity腰围瘦下来_第1张图片
image.png

注意:以下代码均取自Fazhi项目wanggang老师的教学代码 最后我会提供代码供大家下载 不用担心!

第一步 准备工作 定义基类接口

1.定义BaseView接口 一些公用的回调

public interface BaseView {
    void showError(String error);// 展示错误的回调
    void showLoading();// 展示开始请求的Loading
    void hideLoading();// 隐藏开始请求的Loading
    Context getContext();// 用来获取Context上下文
}

2.定义BaseModel接口

public interface BaseModel {
    // 暂时为空 方便日后更改统一的东西 
}

3.定义BasePresenter接口

public interface BasePresenter{
    // 暂时为空 
}

4.定义BaseActivity、BaseFragment、Bean类

这些不用在说了把 随便你门怎么搞 不知道搞就空着放在哪里 预留 相信我总有天你要用的

第二步 继承第一步定义的基类,并拓展一些该业务需求的方法

1.继承基础的BaseView

定义出不同业务需求下的拓展View接口,为什么我门不直接在BaseView接口中就定义好呢? 主要是为了之后的拓展,基类我门只做公共的事情,而这里很明显,不同的请求成功后需要返回的参数的数量不一样和参数类型也可能不同。
在这里我门主要是讲Login需求,那么登陆成功后,需要成功的回调并且传递成功后的参数给activity,去显示提示用户或者更新UI,所以我门返回UserBean这个实体类。

public interfaceI LoginView extends BaseView{
    void showHint(UserBean userBean);
}

2.继承基础的BaseModel

Model负责访问数据 那么我门定义好登陆的请求接口 用来返回Observable>这个可观察者对象

public interface LoginModel extends BaseModel {
    Observable>(String username, String passwrod);//登陆
}

3.继承基础的BasePresenter

Presenter连接View和Model的桥梁 具体待会看代码就知道为什么了

public interface LoginPresenter {
    void login(String username, String passwrod);//登陆
}

第三步 实现刚才我门拓展的接口

1.实现Model中的login方法,调用我门之前封装好的Retrofit + Rxjava + OkHttp请求库,完成请求并返回Observable这个可观察对象,Presenter这个中间人拿到了观察者对象就可以处理订阅结果。

public class LoginModelImple implements ILoginModel {
    @Override
    public Observable> login(String username, String passwrod) {
        HashMap map = new HashMap<>();
        map.put("username", username);
        map.put("password", passwrod);
        RequestBody requestBody = NetRequest.generateReqBody(map);
        return NetRequest.getInstance().getApi().userLogin(requestBody);
    }
}

2.实现PresenterImpl层有具体的请求逻辑(比如事先判断参数是否为空这些),并且还持有module和view层,可以在命令Model请求完结果后,把结果由View回调给Activity处理成功失败的操作,是名副其实的桥梁....

public class LoginPresenterImpl implements ILoginPresenter {

    private ILoginModel model;
    private ILoginView view;

    public LoginPresenterImpl(ILoginView view) {
        this.model = new LoginModelImple();
        this.view = view;
    }

    @Override
    public void login(String username, String passwrod) {
        if(TextUtils.isEmpty(username)){
            view.showError("账号不能为空");
            return;
        }
        if(TextUtils.isEmpty(passwrod)){
            view.showError("密码不能为空");
            return;
        }
        Observable> login = model.login(username, passwrod);
        login.compose(RxHelper.schedulers())
             .compose(RxHelper.transform())
             .subscribe(new NetSubscriber() {
                 @Override
                 public BaseView getView() {
                     return view;
                 }

                 @Override
                 public void onNext(UserBean userBean) {
                     // 保存值 以备下次验证使用
                     LocalData.putSessionKey(userBean.getSession_key());
                     LocalData.putUserID(userBean.getUser_id());

                     // 跳转到首页

                     // 登陆成功 回调Activity
                     view.showHint(userBean);
                }
            });
    }
}

3.最后当然是看看Activity中到底有多小的腰围啦!(惊讶!~~好干净整洁的Activity)

注意View层是Activity实现的 用来接收LoginPresenterImpl这个桥梁中间人反回给我门的结果哦!

public class LoginActivity extends BaseActivity implements ILoginView {

    @BindView(R.id.login_et_phone)
    EditText loginEtPhone;
    @BindView(R.id.login_et_pasd)
    EditText loginEtPasd;
    private LoginPresenterImpl loginPresenter;
    private LoadingDialog loadingDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        loginPresenter = new LoginPresenterImpl(this);
    }


    @OnClick(R.id.login_btn_login)
    public void onClick() {
        loginPresenter.login(loginEtPhone.getText().toString(), loginEtPasd.getText().toString());
    }

    @Override
    public void showHint(UserBean userBean) {
        ToastUtils.showToast(this, userBean.getNickname());
    }

    @Override
    public void showError(String error) {
        ToastUtils.showErrorToast(this, error);
    }

    @Override
    public void showLoading() {
        loadingDialog = new LoadingDialog(this);
        loadingDialog.show();
    }

    @Override
    public void hideLoading() {
        loadingDialog.dismiss();
    }

    @Override
    public Context getContext() {
        return this;
    }
}

老铁们,有了第一次写帖子,自然也有第二次是把?

fazhi项目框架 Git下载 (向作者wanggang老师致敬)

你可能感兴趣的:(MVP项目架构 - 让你的Activity腰围瘦下来)