RxJava系列1:网络请求中的线程切换

学习小目标:
1、使用RxJava + Retrofit 进行网络请求数据,并在TextView中显示结果

2、掌握RxJava线程切换的使用方法

RxJava中的线程切换

一般来说我们在使用网络请求数据后需要使用View来显示,网络请求当然是在子线程中运行,当获取到数据后就需要切换到UI线程来显示,否则会报错,RxJava中已经帮我们处理好了线程切换的问题。

Observable类两个接口


@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> subscribeOn(Scheduler scheduler) {
    ObjectHelper.requireNonNull(scheduler, "scheduler is null");
    return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}

@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> observeOn(Scheduler scheduler) {
    return observeOn(scheduler, false, bufferSize());
}

上面两个接口是用来做什么用的呢?

Observable<T> subscribeOn(Scheduler scheduler)

注释直接翻译:在指定的Scheduler上异步订阅Observers到此ObservableSource

听起来不太好理解,应该这样说:在指定的调度线程上给可观察源异步的订阅观察者

Observable<T> observeOn(Scheduler scheduler)

注释直接翻译:修改ObservableSource以在指定的Scheduler上执行其发射和通知

也不太好理解,可以这样说:修改被观察源到指定的调度线程上去执行发射或通知(也就是说在另一个线程上去执行某些方法)

看了上面解释可能还是一头雾水,现在结合世界场景来理解,看下面示例代码


请求接口定义
public interface NetService {

    @GET("?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json")
    Observable<WeatherBeans> requestWeatherBeansRX();


}


接口使用
private void doGetWithRx() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Observable<WeatherBeans> observable = netService.requestWeatherBeansRX();
        observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<WeatherBeans>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe run");
                    }

                    @Override
                    public void onNext(WeatherBeans beans) {
                        StringBuilder sb = new StringBuilder();
                        if (beans != null) {
                            for (WeatherBeans.ResultBean bean : beans.getResult()) {
                                Log.d(TAG, "cityName:" + bean.getCitynm());
                                sb.append(bean.getCitynm()).append("、");
                            }
                            resultView.setText(sb.toString());

                        } else {
                            Log.d(TAG, "OnNext beans is null");
                        }
                    }

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

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

从上面的示例代码我们看到在网络请求的链式调用。

observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())...

先看subscribeOn(Schedulers.io())

Schedulers.io()的注释是:创建并返回用于IO绑定工作的Scheduler

那么subscribeOn也就是在io运行线程订阅,也就是说网络请求io操作在io线程

再看observeOn(AndroidSchedulers.mainThread())

AndroidSchedulers.mainThread():一个Scheduler,它在Android主线程上执行操作

这两个接口的作用是如下:

subscribeOn(Schedulers.io())是指定observable的subscribeOn() 方法在后台线程运行。

observeOn(AndroidSchedulers.mainThread())是指定 observer 的回调方法在主线程运行。

实验1

注释subscribeOn(Schedulers.io())

结果输出:

09-27 14:48:51.520 2879-2879/hq.demo.net D/NewOkHttpFragment: onSubscribe run
09-27 14:48:51.556 2879-2879/hq.demo.net D/NewOkHttpFragment: onError run

可以看到回调了onError,说明请求错误了

实验2

注释掉observeOn(AndroidSchedulers.mainThread())

结果输出:

09-27 14:54:49.481 4059-4059/hq.demo.net D/NewOkHttpFragment: onSubscribe run
09-27 14:54:49.735 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.735 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.736 4059-4099/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:54:49.738 4059-4099/hq.demo.net D/NewOkHttpFragment: OnError run

上面结果说明网络请求结果成功,但是resultView.setText(sb.toString());出错,

实验3

去掉所有注释

结果输出:

09-27 14:58:51.008 4349-4349/hq.demo.net D/NewOkHttpFragment: onSubscribe run
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.230 4349-4349/hq.demo.net D/NewOkHttpFragment: cityName:北京
09-27 14:58:51.232 4349-4349/hq.demo.net D/NewOkHttpFragment: onComplete run

总结:

RxJava在数据请求展示中的线程切换是通过下面接口处理的,

1、subscribeOn(Schedulers.io())   指定observable的 subscribeOn() 方法在后台线程运行。

2、observeOn(AndroidSchedulers.mainThread())  指定 observer 的回调方法在主线程运行。

猜你喜欢

转载自blog.csdn.net/weixin_36709064/article/details/82839599