zoukankan      html  css  js  c++  java
  • Retrofit+MVP框架封装记录篇

    当下最流行的网络请求组合,retrofit2+okhttp+rxjava+mvp

    这里是封装记录篇

    首先分模块,比如登录

    先来说封装后的使用

    package com.fragmentapp.login.presenter;
    
    import android.util.Log;
    
    import com.fragmentapp.base.BasePresenter;
    import com.fragmentapp.http.BaseObserver;
    import com.fragmentapp.http.BaseResponses;
    import com.fragmentapp.login.bean.LoginDataBean;
    import com.fragmentapp.login.imple.ILoginModel;
    import com.fragmentapp.login.imple.ILoginView;
    import com.fragmentapp.login.model.LoginModel;
    
    /**
     * Created by liuzhen on 2017/11/3.
     */
    
    public class LoginPresenter extends BasePresenter {
    
        private ILoginView view;
        private ILoginModel model;
    
        public LoginPresenter(ILoginView view){
            this.view = view;
            model = new LoginModel();
        }
    
        public void login(String username,String pwd){
            model.login(observer,username,pwd);
        }
    
        BaseObserver<BaseResponses<LoginDataBean>> observer = new BaseObserver<BaseResponses<LoginDataBean>>(){
    
            @Override
            public void onNextResponse(BaseResponses<LoginDataBean> loginDataBean) {
                Log.e("token",loginDataBean.getData().getHCACCESSTOKEN()+"");
                view.success(loginDataBean.getData());
            }
    
            @Override
            public void onErrorResponse(BaseResponses<LoginDataBean> loginDataBean) {
                view.error();
            }
    
            @Override
            public void onNetWorkError(String val) {
                view.error();
            }
        };
    
    }
    Presenter

    通过p层的接口来交互,model去访问网络请求,然后返回结果回调返回到view层去刷新

    这里自定义了一个base的obsever类,避免多次的传递接口

    model则负责调用网络请求了

    package com.fragmentapp.login.model;
    
    import com.fragmentapp.http.BaseObserver;
    import com.fragmentapp.http.BaseResponses;
    import com.fragmentapp.http.RetrofitHelper;
    import com.fragmentapp.login.bean.LoginDataBean;
    import com.fragmentapp.login.imple.ILoginModel;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import io.reactivex.android.schedulers.AndroidSchedulers;
    import io.reactivex.schedulers.Schedulers;
    
    /**
     * Created by liuzhen on 2017/11/7.
     */
    
    public class LoginModel implements ILoginModel {
    
        @Override
        public void login(final BaseObserver<BaseResponses<LoginDataBean>> observer,String username,String pwd) {
            Map<String, String> map = new HashMap<>();
            map.put("account[username]", username);
            map.put("account[password]", pwd);
            RetrofitHelper.getInstance().getService()
                    .login(map)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(observer);
        }
    
    }
    View Code

    view层的回调也只有两个接口,可以根据自己的需求添加

    package com.fragmentapp.login.imple;
    
    import com.fragmentapp.login.bean.LoginDataBean;
    
    /**
     * Created by liuzhen on 2017/11/6.
     */
    
    public interface ILoginView {
    
        void success(LoginDataBean dataBean);
        void error();
    
    }
    View Code

    访问网络后直接在activity里处理回调的结果刷新界面等

    这里的retrofit的访问url是用的添加头部tag来达到动态访问替换baseurl的目的

    然后接口参数采用map的方式添加,个人感觉一个个分开来跟烦,每次都得改service类

    然后observable套用了一层类型,这里主要是后台数据格式吭,可以去掉

    package com.fragmentapp.http;
    
    /**
     * Created by liuzhen on 2017/11/3.
     */
    
    public class BaseResponses<T> {
    
        private String info;
        private int status;
        private T data;
    
        public String getInfo() {
            return info;
        }
    
        public void setInfo(String info) {
            this.info = info;
        }
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    }
    View Code

    然后是base的observer类,在里面根据自己的业务去回调自定义的接口,这样就不用每次重载这么多的方法了

    package com.fragmentapp.http;
    
    import android.os.Looper;
    import android.util.Log;
    
    import io.reactivex.Observer;
    import io.reactivex.disposables.Disposable;
    
    /**
     * Created by liuzhen on 2017/11/3.
     */
    
    public abstract class BaseObserver<T extends BaseResponses> implements Observer<T> {
        String TAG = getClass().getSimpleName();
    
        @Override
        public void onSubscribe(Disposable d) {
            Log.e(TAG, "onSubscribe");
        }
    
        @Override
        public void onNext(T t) {
            Log.e(TAG, "onNext"+t);
            if (t.getStatus() == 200) {
                onNextResponse(t);
            } else {
                Log.e(TAG, "ErrorStatus:" + t.getStatus() + "ErrorInfo" + t.getInfo());
                onErrorResponse(t);
            }
        }
    
        @Override
        public void onError(Throwable e) {
            Log.e(TAG, "onError" + e.toString());
            onNetWorkError("onError 网络超时,请重新尝试--"+e.getMessage());
            if (Looper.myLooper() == null) {
                Looper.prepare();
                Log.e(TAG,"onError 网络超时,请重新尝试");
                Looper.loop();
            }
    
        }
    
        @Override
        public void onComplete() {
            Log.e(TAG, "onComplete");
        }
    
        /**返回成功*/
        public abstract void onNextResponse(T t);
        /**接口失败信息*/
        public abstract void onErrorResponse(T t);
        /**网络错误*/
        public abstract void onNetWorkError(String val);
    }
    View Code

    这个没啥好说的了

    封装好了添加东西也就方便许多了,前面的工作不就是为了后期的迭代方便吗

    比如添加一个dialog加载框,首先先添加两个回调方法

    然后统一在observer里调用接口方法

    只需要在presenter层的回调的统一调用就行了,在view层完全不用理会,而且逻辑的控制也能很好的添加,然后在view层实现方法,在方法里去调用dialog的show方法

    至于这里的dialog是自己自定义了一个简单的progress控件,然后在base里面去操作的,这样在view加载的时候直接调用方法就行了,这里是和空页面一起操作的,空页面有专门写,在上一篇

    效果如下图

    GitHub:https://github.com/1024477951/FragmentApp

  • 相关阅读:
    散列函数之单散列算法
    NET 使用 RabbitMQ
    leetCode
    Swift 1
    C#并发集合
    多进程与多线程1
    开发编译器
    APUE1
    微服务架构
    ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”
  • 原文地址:https://www.cnblogs.com/LiuZhen/p/8145712.html
Copyright © 2011-2022 走看看