【Android】RxJava + Retrofit完成网络请求

RxJava详解
Retrofit 2.0 的使用
RxJava的使用(一)基本用法
RxJava + Retrofit完成网络请求

先看一个Demo:

    private void Demo1() {
        String[] a = {"" + R.mipmap.ic_launcher};
        String[][] folders = {a, a};
        Log.i(TAG, "thread0: " + Thread.currentThread().getId());
        Observable
                .from(folders)
                .flatMap(new Func1<String[], Observable<String>>() {//String[]转换成String
                    @Override
                    public Observable<String> call(String[] file) {
                        Log.i(TAG, "flatMap: " + Thread.currentThread().getId());
                        return Observable.from(file);
                    }
                })
                .filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String file) {
                        Log.i(TAG, "filter: " + Thread.currentThread().getId());
                        return file instanceof String;//false 过滤, true 不过滤
                    }
                })
                .map(new Func1<String, Integer>() {//String 转换成 Integer
                    @Override
                    public Integer call(String file) {
                        Log.i(TAG, "Func1: " + Thread.currentThread().getId());
                        return Integer.parseInt(file);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer bitmap) {
                        Log.i(TAG, "Action1-Next: " + Thread.currentThread().getId());
                        iv_img.setBackgroundResource(bitmap);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.i(TAG, "Action1-Error: " + Thread.currentThread().getId());
                    }
                }, new Action0() {
                    @Override
                    public void call() {
                        Log.i(TAG, "Action1-Completed: " + Thread.currentThread().getId());
                    }
                });
    }

运行结果:

09-22 18:14:50.569 20855-20855/com.test.git.rxjavademo I/MainActivity-: thread0: 1
09-22 18:14:50.609 20855-31005/com.test.git.rxjavademo I/MainActivity-: flatMap: 22105
09-22 18:14:50.609 20855-31005/com.test.git.rxjavademo I/MainActivity-: filter: 22105
09-22 18:14:50.609 20855-31005/com.test.git.rxjavademo I/MainActivity-: Func1: 22105
09-22 18:14:50.609 20855-31005/com.test.git.rxjavademo I/MainActivity-: flatMap: 22105
09-22 18:14:50.609 20855-31005/com.test.git.rxjavademo I/MainActivity-: filter: 22105
09-22 18:14:50.609 20855-31005/com.test.git.rxjavademo I/MainActivity-: Func1: 22105
09-22 18:14:50.639 20855-20855/com.test.git.rxjavademo I/MainActivity-: Action1-Next: 1
09-22 18:14:50.649 20855-20855/com.test.git.rxjavademo I/MainActivity-: Action1-Next: 1
09-22 18:14:50.649 20855-20855/com.test.git.rxjavademo I/MainActivity-: Action1-Completed: 1

可以看出log输出与代码结构一致,所以RxJava的优点在于简洁,即使逻辑很复杂,线程切换也很方便。

RxJava:一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。

build.gradle添加依赖:

    compile 'io.reactivex:rxjava:1.2.0'
    compile 'io.reactivex:rxandroid:1.2.1'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'

创建观察者

有两种方式
第一种:

        Observer<String> observer = new Observer<String>() {
            @Override
            public void onCompleted() {
                Log.i(TAG, "Observer-onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "Observer-onError: ");
            }

            @Override
            public void onNext(String s) {
                Log.i(TAG, "Observer-onNext: " + s);
            }
        };

第二种:

        Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onStart() {
                super.onStart();
                Log.i(TAG, "Subscriber-onStart: ");
            }

            @Override
            public void onCompleted() {
                Log.i(TAG, "Subscriber-onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "Subscriber-onError: ");
            }

            @Override
            public void onNext(String s) {
                Log.i(TAG, "Subscriber-onNext: ");
            }
        };

被观察者

有三种方式:
第一种:

        Observable observable1  = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Hello");
                subscriber.onNext("Rx");
                subscriber.onNext("Java");
                subscriber.onNext("One");
                subscriber.onCompleted();
            }
        });

第二种:

    Observable observable2 = Observable.just("Hello", "Rx", "Java", "Two");

第三种:

        String[] words = {"Hello", "Rx", "Java", "Three"};
        Observable observable3 = Observable.from(words);

观察者与被观察者订阅

subscriber()做了三件事:
1.调用Subscriber.onStart()
2.调用Observable的OnSubscrible.call(Subscriber);
3.将传入的Subscriber作为Subscription返回,为了方便unsubscribe();

根据观察者创建方式不同订阅方式也不同:
方式一:

        observable1.subscribe(observer);

方式二:

        observable2.subscribe(subscriber);

Demo:

    /**
     * Observer Observable
     */
    private void Demo2(){
        /**
         * 1.创建观察者Observer
         */
        Observer<String> observer = new Observer<String>() {
            @Override
            public void onCompleted() {
                Log.i(TAG, "Observer-onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "Observer-onError: ");
            }

            @Override
            public void onNext(String s) {
                Log.i(TAG, "Observer-onNext: " + s);
            }
        };


        Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onStart() {
                super.onStart();
                Log.i(TAG, "Subscriber-onStart: ");
            }

            @Override
            public void onCompleted() {
                Log.i(TAG, "Subscriber-onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "Subscriber-onError: ");
            }

            @Override
            public void onNext(String s) {
                Log.i(TAG, "Subscriber-onNext: ");
            }
        };

//        subscriber.isUnsubscribed();//判断状态
//        subscriber.unsubscribe();//取消订阅,尽量在onpause或onstop调用,防止内存泄漏
        /**
         * 2.创建被观察者Observable
         */
        //type one
        Observable observable1  = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Hello");
                subscriber.onNext("Rx");
                subscriber.onNext("Java");
                subscriber.onNext("One");
                subscriber.onCompleted();
            }
        });
        //type two
        Observable observable2 = Observable.just("Hello", "Rx", "Java", "Two");
        //type three
        String[] words = {"Hello", "Rx", "Java", "Three"};
        Observable observable3 = Observable.from(words);


        /***
         * 订阅Subscribe
         */
        observable1.subscribe(observer);
        observable2.subscribe(subscriber);
        //subscriber()做了三件事:
        //1.调用Subscriber.onStart()
        //2.调用Observable的OnSubscrible.call(Subscriber);
        //3.将传入的Subscriber作为Subscription返回,为了方便unsubscribe();

    }

输出结果:

09-22 18:37:59.359 26737-26737/com.test.git.rxjavademo I/MainActivity-: Observer-onNext: Hello
09-22 18:37:59.359 26737-26737/com.test.git.rxjavademo I/MainActivity-: Observer-onNext: Rx
09-22 18:37:59.359 26737-26737/com.test.git.rxjavademo I/MainActivity-: Observer-onNext: Java
09-22 18:37:59.359 26737-26737/com.test.git.rxjavademo I/MainActivity-: Observer-onNext: One
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Observer-onCompleted: 
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Demo2: ------------------------------------------------
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Subscriber-onStart: 
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Subscriber-onNext: Hello
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Subscriber-onNext: Rx
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Subscriber-onNext: Java
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Subscriber-onNext: Two
09-22 18:37:59.369 26737-26737/com.test.git.rxjavademo I/MainActivity-: Subscriber-onCompleted: 

Action0 Action1

Action0 无参
Action1 有参

Demo:

    private void Demo3(){
        /**
         * Action1有参
         * Action0无参
         */
        Action1<String> onNextAction = new Action1<String>() {
            @Override
            public void call(String s) {
                Log.i(TAG, "onNextAction-call: " + s);
            }
        };

        Action1<Throwable> onErrorAction = new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                Log.i(TAG, "onErrorAction-call: ");
            }
        };

        Action0 onCompletedAction = new Action0() {
            @Override
            public void call() {
                Log.i(TAG, "onCompletedAction-call: ");
            }
        };
        Observable observable = Observable.just("Hello", "Rx", "Java", "Two");

        observable.subscribe(onNextAction);

        observable.subscribe(onNextAction, onErrorAction);

        observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
    }

输出结果:

09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Hello
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Rx
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Java
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Two
09-22 18:41:36.709 4256-4256/? I/MainActivity-: Demo3: -----------------
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Hello
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Rx
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Java
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Two
09-22 18:41:36.709 4256-4256/? I/MainActivity-: Demo3: -----------------
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Hello
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Rx
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Java
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onNextAction-call: Two
09-22 18:41:36.709 4256-4256/? I/MainActivity-: onCompletedAction-call: 

Schedulers和AndroidSchedulers 线程切换

  • Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
  • Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • 另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。

Demo:

    private void Demo4(){
        final int drawableRes = R.mipmap.ic_launcher;
        Observable.create(new Observable.OnSubscribe<Drawable>() {

            @Override
            public void call(Subscriber<? super Drawable> subscriber) {
                Log.i(TAG, "call: " + Thread.currentThread().getId());
                Drawable drawable = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    drawable = getTheme().getDrawable(drawableRes);
                }
                subscriber.onNext(drawable);
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io())//指定subscribe()发生在IO线程
                .observeOn(AndroidSchedulers.mainThread())//指定Subscriber的回调发生在主线程
//                .subscribe(new Action1<Drawable>() {
//                    @Override
//                    public void call(Drawable drawable) {
//
//                    }
//                })
                .subscribe(new Observer<Drawable>() {

                    @Override
                    public void onCompleted() {
                        Log.i(TAG, "onCompleted: ");
                    }

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

                    @Override
                    public void onNext(Drawable drawable) {
                        Log.i(TAG, "onNext: " + Thread.currentThread().getId());
                        if(drawable == null){
                            iv_img.setImageResource(android.support.v7.appcompat.R.drawable.abc_list_focused_holo);
                        }else {
                            iv_img.setImageDrawable(drawable);
                        }
                    }
                });
    }

log:

09-22 18:45:43.249 4256-7931/com.test.git.rxjavademo I/MainActivity-: call: 22217
09-22 18:45:43.279 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 1
09-22 18:45:43.279 4256-4256/com.test.git.rxjavademo I/MainActivity-: onCompleted: 

map

demo:

    private void Demo5(){
        String s = "1";
        Observable.just(s)
                .map(new Func1<String, Integer>() {//String 转换成 Integer
                    @Override
                    public Integer call(String ss) {
                        Log.i(TAG, "Func1-call: " + ss);
                        return Integer.parseInt(ss);
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer s) {
                        Log.i(TAG, "Action1-call: " + s);
                    }
                });
    }

log:

09-22 18:46:48.039 4256-4256/com.test.git.rxjavademo I/MainActivity-: Func1-call: 1
09-22 18:46:48.039 4256-4256/com.test.git.rxjavademo I/MainActivity-: Action1-call: 1

flatMap

Demo:

    private void Demo6(){
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        Map<String, List<Integer>> map = new HashMap<>();
        map.put("a", nums);
        List<Map<String, List<Integer>>> list = new ArrayList<>();
        list.add(map);
        list.add(map);
        list.add(map);

        Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.i(TAG, "onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getMessage());
            }

            @Override
            public void onNext(Integer ls) {
                Log.i(TAG, "onNext: " + ls);
            }
        };

        Observable.from(list)
                .flatMap(new Func1<Map<String, List<Integer>>, Observable<Integer>>() {
                    @Override
                    public Observable<Integer> call(Map<String, List<Integer>> ls) {
                        Log.i(TAG, "call: ");
                        List<Integer> a = ls.get("a");
                        return Observable.from(a);
                    }
                })
                .subscribe(subscriber);
    }

log:

09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: call: 
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 1
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 2
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 3
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: call: 
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 1
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 2
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 3
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: call: 
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 1
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 2
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onNext: 3
09-22 18:48:46.529 4256-4256/com.test.git.rxjavademo I/MainActivity-: onCompleted: 

doOnSubscribe

Demo:

    private void Demo7(){
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                Log.i(TAG, "OnSubscribe-call: " + Thread.currentThread().getId());
                subscriber.onNext("test");
                subscriber.onCompleted();
            }
        })
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        Log.i(TAG, "Action0-call: " + Thread.currentThread().getId());
                        iv_img.setImageResource(R.mipmap.ic_launcher);//需要在主线程
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())//指定主线程
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, "Action1-call: " + s + "  thread:" + Thread.currentThread().getId());
                    }
                });
    }

log:

09-22 18:50:27.729 4256-4256/com.test.git.rxjavademo I/MainActivity-: Action0-call: 1
09-22 18:50:27.749 4256-12182/com.test.git.rxjavademo I/MainActivity-: OnSubscribe-call: 22230
09-22 18:50:27.769 4256-4256/com.test.git.rxjavademo I/MainActivity-: Action1-call: test  thread:1

Retrofit

使用介绍

    private void Demo8(){
        //1.创建Retrofit对象
        //2.声明接口NewsService
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl("https://www.baidu.com/")
                .build();

        //3.创建api请求
        NewsService api = retrofit.create(NewsService.class);

        //4.发请求
        final Call<ResponseBody> call = api.getNewss("123");
        //同步调用
        new Thread(new Runnable() {
            @Override
            public void run() {
                Response<ResponseBody> response = null;
                try {
                    response = call.execute();
                    Log.i(TAG, "Demo8-ok1: " + response.headers());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        Log.i(TAG, "Demo8: ---------------------------------------------------");

        //异步调用
//        call.enqueue(new Callback<ResponseBody>() {
//            @Override
//            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//                Log.i(TAG, "Demo8-ok2: " + response.headers());
//            }
//
//            @Override
//            public void onFailure(Call<ResponseBody> call, Throwable t) {
//                Log.i(TAG, "Demo8-Error: " + t.getMessage());
//            }
//        });
        //取消请求
//        call.cancel();
    }


    public interface NewsService{
        /**
         *
         * @param newsId
         * @return
         */
//        @GET("News/{newsId}")
//        Call<News> getNews(@Path("newsId") String newsId);
        /**
         *
         * @param newsId
         * @return
         */
        @GET("News/{newsId}")
        Call<ResponseBody> getNewss(@Path("newsId") String newsId);

        @GET
        Call<List<String>> getSubjectsList(
                @Url String url,
                @QueryMap Map<String, Object> map
        );
    }

RxJava + Retrofit

    private void Demo9(){
        //http://test.api.loookapp.cn/api/banner/list?type=0
        //1.创建Retrofit对象
        //2.声明接口NewsService
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl("https://www.baidu.com/")
                .build();

        //3.创建api请求
        UserService api = retrofit.create(UserService.class);
        api.getUser("123")
                .subscribeOn(Schedulers.newThread())//请求线程在新的线程
                .observeOn(AndroidSchedulers.mainThread())//结果在主线程
                .subscribe(new Observer<BannerListResp>() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG, "onCompleted: ");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG, "onError: " + e.getMessage());
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(BannerListResp resp) {
                        Log.i(TAG, "onNext: " + resp.banners.size());
                    }
                });
    }

    public interface UserService{
        String USER_INFO = "sku";

        @GET(USER_INFO)
        Observable<BannerListResp> getUser(@Query("sku_id") String sku_id);
    }

rxbinding

github地址:rxbinding

    /**
     * 防抖点击(500ms内重复点击只记一次点击)
     */
    private void Demo10(){
        RxView.clicks(iv_img)
                .throttleFirst(500, TimeUnit.MILLISECONDS)
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        Log.i(TAG, "call: click");
                    }
                });
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值