学习RxJava+Retrofit+OkHttp+MVP的网络请求使用

公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了。

我在网上找了很多文章,写的都很详细,比如

https://www.jianshu.com/u/5fd2523645da

https://www.jianshu.com/p/193d8c37c73c

趁热打铁,写一篇学习笔记,理顺思路。

先把他们都引入
//rxjava
    compile 'io.reactivex.rxjava2:rxjava:2.2.0'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.2'
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

    //retrofit
    compile 'com.squareup.retrofit2:retrofit:2.3.0'

    //okhttp
    compile 'com.squareup.okhttp3:okhttp:3.11.0'
    compile 'com.squareup.okio:okio:1.14.0'
   implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
    //gson 
implementation 'com.google.code.gson:gson:2.8.4' implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

一、RxJava学习

简单的说,核心是观察者模式。那么这个就很有意思了,举个栗子

 

我订阅了公众号之后就可以去干其他的事了,当公众号有新的文章之后发个消息通知我:有新文章了。这时我再点开去查看。

RxJava中有这几种方法

onNext():一直向我推送文章
onComplete():文章推送完了
onError():推送出现异常,同时终止,不再有消息发出.
onSubscribe():RxJava 2.0 中新增的,传递参数为Disposable,可用于切断接收事件

RxJava的链式操作

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        })
                .observeOn(AndroidSchedulers.mainThread())//回调在主线程
                .subscribeOn(Schedulers.io())//执行在io线程
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "onNext=" + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete");
                    }
                });

线程切换流程(observeOn与subscribeOn)

当前为主(main)线程,订阅(向上走)

1.开始 subscribe 订阅

2.经 subscribeOn 将线程切换为IO线程(Schedulers:线程调度器)

3.经 observeOn 控制数据流的,跳过

4.经 create 在IO线程中执行

到这里,订阅完成,开始发射数据。

当前为IO线程,发射数据(向下走)

1.经 observeOn 将线程切换为主(main)线程

2.经 subscribeOn 控制订阅的,跳过

3.经 onNext 在主线程中执行

 整个流程就走完了。

RxJava还有很多操作符,等后面慢慢学习。

二、Retrofit学习

简单的说,它是网络适配器,通过OkHttp发送请求

它是将okhttp进行了进一步的封装翻新

偷张图哈哈哈 https://www.jianshu.com/p/15edb4de0f62

三、进入正题,打通网络请求

1.Retrofit封装

创建Api接口

public interface IApiService {
    @POST("/lay-eggs/androidtest.php")
    Observable<TestBean> getData(@Query("time") String time);
}

 也可以用@QueryMap 直接整一个集合上去。

TestBean用JsonFormat自动生成

创建Retrofit管理类

public class RetrofitManager {
    private static RetrofitManager retrofitManager;
    private Retrofit retrofit;
    private static final String BASE_URL="http://yyyxuan.cn";//根地址
    private IApiService apiService;

    /**
     * 单例模式
     * @return
     */
    public static RetrofitManager getInstance (){
        if (retrofitManager==null){
            synchronized (RetrofitManager.class){
                if (retrofitManager==null){
                    retrofitManager= new RetrofitManager();
                }
            }
        }
        return retrofitManager;
    }

    //构造函数
    private RetrofitManager(){
        initRetrofitManager();
    }

    //创建Retrofit实例
    private void initRetrofitManager() {
        retrofit=new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())//对服务器数据进行解析
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//RxJava适配器
                .build();
        apiService=retrofit.create(IApiService.class);
    }


    public IApiService apiservice(){return apiService;}

}

 2.订阅关系处理

定义添加删除订阅关系的接口

public interface SubscriptionHelper<T> {

    /**
     * 添加
     * @param disposable
     */
    void add(Disposable disposable);

    /**
     * 取消
     * @param disposable
     */
    void cancel(Disposable disposable);

    /**
     * 取消所有
     */
    void cancelAll();
}

创建订阅关系管理类

public class SubscriptionManager implements SubscriptionHelper<Object> {

    public static SubscriptionManager subscriptionManager;
    private CompositeDisposable mDisposables;//存放disposable容器

    /**
     * 构造函数 new CompositeDisposable对象
     */
    public SubscriptionManager(){
        if (mDisposables==null){
            mDisposables=new CompositeDisposable();
        }
    }

    /**
     * 单例
     * @return
     */
    public static SubscriptionManager getInstance(){
        if (subscriptionManager==null){
            synchronized (SubscriptionManager.class){
                if (subscriptionManager==null){
                    subscriptionManager=new SubscriptionManager();
                }
            }
        }
        return subscriptionManager;
    }

    /**
     * 订阅事件加入到CompositeDisposable容器中
     * @param disposable 订阅事件
     */
    @Override
    public void add(Disposable disposable) {
        if(disposable==null) return;
        mDisposables.add(disposable);
    }

    /**
     * 取消订阅事件
     * @param disposable 订阅事件
     */
    @Override
    public void cancel(Disposable disposable) {
        if (disposable!=null){
            mDisposables.delete(disposable);
        }
    }

    /**
     * 清除容器所有
     */
    @Override
    public void cancelAll() {
        if (mDisposables!=null){
            mDisposables.clear();
        }
    }
}

 3.异常处理

网上有很多异常处理的类,可以去搜一下(忘记我看的哪篇文章了)

public class ExceptionHandle {

    private static final int UNAUTHORIZED = 401;
    private static final int FORBIDDEN = 403;
    private static final int NOT_FOUND = 404;
    private static final int REQUEST_TIMEOUT = 408;
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int BAD_GATEWAY = 502;
    private static final int SERVICE_UNAVAILABLE = 503;
    private static final int GATEWAY_TIMEOUT = 504;


    public static ResponseException handleException(Throwable e){

        //转换成ResponseException,根据状态码判定错误信息
        ResponseException ex;
        if(e instanceof HttpException){
            HttpException httpException=(HttpException)e;
            /**
             * 传入状态码,根据状态码判定错误信息
             */
            ex=new ResponseException(e,ERROR.HTTP_ERROR);
            switch (httpException.code()){
                case UNAUTHORIZED:
                    ex.message="未验证";
                    break;
                case FORBIDDEN:
                    ex.message="服务禁止访问";
                    break;
                case NOT_FOUND:
                    ex.message="服务不存在";
                    break;
                case REQUEST_TIMEOUT:
                    ex.message="请求超时";
                    break;
                case GATEWAY_TIMEOUT:
                    ex.message="网关超时";
                    break;
                case INTERNAL_SERVER_ERROR:
                    ex.message="服务器内部错误";
                    break;
                case BAD_GATEWAY:

                    break;
                case SERVICE_UNAVAILABLE:
                    break;
                default:
                    ex.message = "网络错误";
                    break;
            }
            return ex;
        }else if(e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException){
            ex=new ResponseException(e,ERROR.PARSE_ERROR);
            ex.message="解析错误";
            return ex;
        }else if(e instanceof ConnectException){
            ex=new ResponseException(e,ERROR.NETWORD_ERROR);
            ex.message="连接失败";
            return ex;
        }else if(e instanceof javax.net.ssl.SSLHandshakeException){
            ex=new ResponseException(e,ERROR.SSL_ERROR);
            ex.message="证书验证失败";
            return ex;
        }else {
            ex=new ResponseException(e,ERROR.UNKNOWN);
            ex.message="未知错误";
            return ex;
        }

    }

    /**
     * 约定异常
     */
    public static class ERROR{
        /**
         * 自定义异常
         */
        private static final int UNAUTHORIZED = 401;//请求用户进行身份验证
        private static final int UNREQUEST=403;//服务器理解请求客户端的请求,但是拒绝执行此请求
        private static final int UNFINDSOURCE=404;//服务器无法根据客户端的请求找到资源
        private static final int SEVERERROR=500;//服务器内部错误,无法完成请求。
        /**
         * 协议出错
         */
        public static final int HTTP_ERROR = 1003;
        /**
         * 未知错误
         */
        public static final int UNKNOWN = 1000;
        /**
         * 解析错误
         */
        public static final int PARSE_ERROR = 1001;
        /**
         * 网络错误
         */
        public static final int NETWORD_ERROR = 1002;
        /**
         * 证书出错
         */
        public static final int SSL_ERROR = 1005;
    }

    /**
     * 自定义Throwable
     */
    public static class ResponseThrowable extends Exception{
        public int code;
        public String message;
        public ResponseThrowable(Throwable throwable,int code){
            super(throwable);
            this.code=code;
        }
    }

    /**
     * 服务器异常
     */
    public class ServerException extends RuntimeException{
        public int code;
        public String message;
    }

    /**
     * 统一异常类,便于处理
     */
    public static class ResponseException extends Exception{
        public int code;
        public String message;
        public ResponseException (Throwable throwable,int code){
            super(throwable);
            this.code=code;
        }
    }

}

4.Observer封装

上面讲到了四个方法以及他们的作用,这里简单的封装一下

public abstract class Observer<T> implements io.reactivex.Observer<T> {
    @Override
    public void onSubscribe(Disposable d) {
        OnDisposable(d);
    }

    @Override
    public void onNext(T t) {
        OnSuccess(t);
    }

    @Override
    public void onError(Throwable e) {
        OnFail(ExceptionHandle.handleException(e));
    }

    @Override
    public void onComplete() {
        OnCompleted();
    }


    protected abstract void OnDisposable(Disposable d);

    protected abstract void OnSuccess(T t);

    protected abstract void OnFail(ExceptionHandle.ResponseException e);

    protected abstract void OnCompleted();
}

5.MVP搭建

 

网上找了很详细的图解

View:负责绘制UI元素、与用户进行交互。

Model:负责存储、检索、操纵数据。

Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

M与V层需要P层来进行通信。

Model层

添加订阅关系,进行网络请求。

public class TestModel {
    public void getTestInfo(String time, Observer<TestBean> observer){
        RetrofitManager.getInstance().apiservice().getData(time)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(observer);
    }
}

各种基类的封装

P层 用来绑定和解除与v层关系

public class BasePresenter<V extends BaseView> {
    public V view;

    /**
     * 添加view
     * @param v
     */
    public void addView(V v){
        this.view=v;
    }

    /**
     * 解除
     */
    public  void breakView(){
        if (view!=null){
            view=null;
        }
    }
}

V层 定义回调功能,可根据不同需求更改

public interface BaseView {

    /**
     * 成功回调
     * @param object
     */
    void onSuccess(Object object);

    /**
     * 失败回调
     * @param t 异常
     */
    void onFail(ExceptionHandle.ResponseException t);

    /**
     * 发射结束
     */
    void onCompleted();
}

activity基类

public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements BaseView {
    public Context context;
    protected P presenter;

    //获取P层
    protected abstract P createPresenter();
    //获取是哪个activity
    protected abstract int getLayoutId();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context=this;
        setContentView(getLayoutId());
        presenter=createPresenter();
        presenter.addView(this);//绑定view
        initView();
        initData();
    }

    public void initData(){

    };

    public void initView(){

    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (presenter != null) {
            presenter.breakView();
            SubscriptionManager.getInstance().cancelAll();
        }
    }
}

真正的Presenter

public class TestPresenter extends BasePresenter<BaseView> {
    private TestModel testModel;
    /**
     * 绑定M层
     */
    public TestPresenter (){
        testModel=new TestModel();
    }

    public void test(String time){
        //网络请求,创建观察者
        testModel.getTestInfo(time, new Observer<TestBean>() {
            @Override
            protected void OnDisposable(Disposable d) {
                SubscriptionManager.getInstance().add(d);
            }

            @Override
            protected void OnSuccess(TestBean testBean) {
                view.onSuccess(testBean);
            }

            @Override
            protected void OnFail(ExceptionHandle.ResponseException e) {
                view.onFail(e);
            }

            @Override
            protected void OnCompleted() {
                view.onCompleted();
            }
        });
    }
}

真正的Activity

public class MainActivity extends BaseActivity<TestPresenter> implements BaseView {
    String TAG="aaa";
    TextView textView;
    Button button;

    /**
     * 绑定p层
     * @return
     */
    @Override
    protected TestPresenter createPresenter() {
        return new TestPresenter();
    }

    /**
     * 加载当前activity
     * @return
     */
    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    /**
     * 成功回调
     * @param object 
     */
    @Override
    public void onSuccess(Object object) {
        Log.d(TAG, "onSuccess: "+beanToJson(object));
        TestBean testBean= (TestBean) object;
        textView.setText(testBean.getData().getContent());
    }

    /**
     * 失败回调
     * @param t 异常
     */
    @Override
    public void onFail(ExceptionHandle.ResponseException t) {
        Log.d(TAG, t.message.toString());
    }

    @Override
    public void onCompleted() {

    }

    public String beanToJson(Object bean) {
        Gson gson = new Gson();
        String jsonStr = gson.toJson(bean);
        return jsonStr;
    }

    /**
     * 初始化界面
     */
    @Override
    public void initView() {
        super.initView();
        textView=findViewById(R.id.mtv);
        button=findViewById(R.id.mbtn);
    }

    /**
     * 初始化数据
     */
    @Override
    public void initData() {
        super.initData();
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.test("123");
            }
        });
    }
}

 别忘了最重要的网络权限(在AndroidManifest.xml)

<uses-permission android:name="android.permission.INTERNET" />

 github:https://github.com/steffenx/RxJava-Retrofit-mvp

6.最后

写下这篇博客是帮助我学习,知识梳理,加深印象。以后也能翻出来看看对吧(狗头)

猜你喜欢

转载自www.cnblogs.com/Steffen-xuan/p/11227430.html