RxJava2.0使用(二)

RxJava中默认就是在哪个线程中发生事件就在哪个线程中消费事件,但是很多时候我们都有这样的需求比如联网请求数据,我们需要在子线程中去联网获取数据,获取到数据之后在主线程中更新UI。这时候就需要切换线程,切换线程使用RxJava 中的Scheduler 翻译过来就是调度器。
RxJava 已经内置了几个 Scheduler

  • Schedulers.newThread() 代表一个常规的新线程
  • Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作 跟Schedulers.newThread()差不多,区别我的理解是线程跟线程池的区别差不多。
  • Schedulers.computation(): CPU 密集型计算 可以充分利用CPU, 需要计算的时候使用
  • AndroidSchedulers.mainThread() 代表Android的主线程

    知道了这些Scheduler 就可以通过subscribeOn() 和 observeOn()两个方法切换线程了。subscribeOn()用来指定事件发生的线程,也就是被观察者所在的线程,observeOn()用来指定消费事件所在的线程,也就是观察者所在的线程。

    简单的应用:

 Observable.create(new ObservableOnSubscribe<Drawable>() {
                    @Override
                    public void subscribe(ObservableEmitter<Drawable> e) throws Exception {
                        Drawable drawable =           ContextCompat.getDrawable(RxJavaActivity.this,R.mipmap.girl);
                        e.onNext(drawable);
                        e.onComplete();
                    }
                })
                        .subscribeOn(Schedulers.io())// 指定 Observable(被观察者 事件) 发生在 IO 线程
                        .observeOn(AndroidSchedulers.mainThread()) // 指定 observer(观察者) 的回调发生在主线程
                        .subscribe(new Consumer<Drawable>() {
                    @Override
                    public void accept(Drawable drawable) throws Exception {
                        iv_img.setImageDrawable(drawable);
                    }
                });

上面的例子中从资源文件夹中获取一张图片转换成Drawable 是运行在io线程中,给imageview设置图片是运行在主线程中。
切换线程的时候subscribeOn()和observeOn()都可以多次调用,不过subscribeOn()只以第一次调用的为准在此调用不会再变化,observeOn()每次调用会作用到它之后的操作中。
小例子:打印一下当前的线程

Observable.just("hello")
                        .subscribeOn(Schedulers.newThread())
                        .doOnNext(new Consumer<String>() {
                            @Override
                            public void accept(String s) throws Exception {
                                Log.i(TAG, "subscribeOn:"+Thread.currentThread().getName());
                            }
                        })
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .doOnNext(new Consumer<String>() {
                            @Override
                            public void accept(String s) throws Exception {
                                Log.i(TAG, "subscribeOn:"+Thread.currentThread().getName());
                            }
                        })
                        .observeOn(Schedulers.io())
                        .doOnNext(new Consumer<String>() {
                            @Override
                            public void accept(String s) throws Exception {
                                Log.i(TAG, "observeOn:"+Thread.currentThread().getName());
                            }
                        })
                        .observeOn(AndroidSchedulers.mainThread())
                        .doOnNext(new Consumer<String>() {
                            @Override
                            public void accept(String s) throws Exception {
                                Log.i(TAG, "observeOn:"+Thread.currentThread().getName());
                            }
                        }).subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.i(TAG, Thread.currentThread().getName());
                    }
                });

输出结果:

 I/com.chs.myrxjavaandretrofit: subscribeOn:RxNewThreadScheduler-1
 I/com.chs.myrxjavaandretrofit: subscribeOn:RxNewThreadScheduler-1
 I/com.chs.myrxjavaandretrofit: observeOn:RxCachedThreadScheduler-1
 I/com.chs.myrxjavaandretrofit: observeOn:main
 I/com.chs.myrxjavaandretrofit: main

可以看到subscribeOn()虽然调用了两次,但是线程没有变,observeOn()调用了两次线程变化了。

恩 最后在来个请求网络的小例子,这里使用豆瓣的一个免费api 和 Retrofit,Retrofit毕竟是当前star数最多的网络框架,而且跟RxJava的结合很友好。
需要先添加3个依赖:

compile 'com.squareup.retrofit2:retrofit:2.3.0'//retrofit版本
compile 'com.squareup.retrofit2:converter-gson:2.3.0'//使用gson解析json
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'//是retrofit跟rxjava2关联
public interface GetDataService {
    @GET("top250")
    Observable<DouBanEntity> getDouBanData(@Query("start") int start, @Query("count") int count);
}

初始化retrofit 并创建rxjava中的Observable (被观察者 或 事件) 指定io线程中执行。指定Observer 观察者在主线程执行。

public class GetServiceClient {
    public static final String BASE_URL = "https://api.douban.com/v2/movie/";

    private static final int DEFAULT_TIMEOUT = 5;

    private Retrofit retrofit;
    private GetDataService getDataService;
    //构造方法私有
    private GetServiceClient() {
        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);

        retrofit = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create())//设置解析器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//跟rxjaba关联
                .baseUrl(BASE_URL)
                .build();

        getDataService = retrofit.create(GetDataService.class);
    }

    //在访问HttpMethods时创建单例
    private static class SingletonHolder{
        private static final GetServiceClient INSTANCE = new GetServiceClient();
    }

    //获取单例
    public static GetServiceClient getInstance(){
        return SingletonHolder.INSTANCE;
    }
    public void getTopMovie(Observer<DouBanEntity> observer, int start, int count){

        Observable<DouBanEntity> observable = getDataService.getDouBanData(start, count);

        toSubscribe(observable, observer);
    }
    private <T> void toSubscribe(Observable<T> o, Observer<T> observer){
                o.subscribeOn(Schedulers.io())//指定Observable
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())//指定observer
                .subscribe(observer);
    }
}

观察者:

   GetServiceClient.getInstance().getTopMovie(new Observer<DouBanEntity>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }
                    @Override
                    public void onNext(DouBanEntity value) {
                        tv_content.setText(value.getTitle()+"\n"+value.getSubjects().get(0).getImages().getLarge());
                        Log.i("TAG",value.getTitle()+"\n"+value.getSubjects().get(0).getImages().getLarge());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                    @Override
                    public void onComplete() {

                    }
                },0,5);

执行结果:

07-12 18:25:50.060 23044-23044/com.chs.myrxjavaandretrofit I/TAG: 豆瓣电影Top250
                                                                  https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p480747492.jpg

项目地址:https://github.com/chsmy/MyRxJavaAndRetrofit

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值