zoukankan      html  css  js  c++  java
  • 学习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.最后

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

  • 相关阅读:
    window查看已保存过的wifi的密码
    js 多个数组取交集
    macOS APP 窗口焦点监听
    proxifier注册码
    天才算法之睡眠排序(C#实现)
    Tomcat 7使用AJP协议设置问题
    nginx启动报错(1113: No mapping for the Unicode character exists in the target multi-byte code page)
    八皇后的n种放置方法
    insufficient permission for adding an object to repository database .git/objects
    centos下搭建php开发环境(lamp)
  • 原文地址:https://www.cnblogs.com/Steffen-xuan/p/11227430.html
Copyright © 2011-2022 走看看