Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

RxJava 1.2.1各个API的使用Demo

$
0
0

前言:

RxJava的介绍之前已经转载了2篇我认为写得比较清楚的。

这篇文章纯粹是我个人学习使用的Demo。

现在rx已经出2.0版本了,不过这里还是1.2的。

提供一下JakeWharton大神的git传送门:https://github.com/JakeWharton

写文章是为了自己在学习过程中梳理一下内容,做一下总结。

没啥文采,见笑。


本文主要内容为RxJava 1.2.1以下内容的使用Demo。

1、事件源的创建,通过Observable.create、from、just。以及Subject

2、过滤事件操作符的使用,包括filter、debounce。

3、线程切换,通过Scheduler类和AndroidSchedulers类。

4、事件转换操作符的使用,包括map、flatmap。


1.1 create

create的作用是创建一个事件源Observable,让它的监听者 Subscriber执行指定的方法。

Returns an Observable that will execute the specified function when a {@link Subscriber} subscribes to it.

Rx中声明了3种crate方法:



这里我只使用了最长用的第二种,另外两种看名字就差不多能猜出和数据同步有关系,比如读写数据库,调用一些有状态的函数等。

下面的代码创建了一个事件源,并让他的监听者弹一个内容为  createTest  的Toast。

Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("createTest");
            }
        }).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {
                Toast.makeText(Activity1.this,s, Toast.LENGTH_LONG).show();
            }
        });


1.2 from


大体上,from可以接收3种参数类型,Future、Iterable(list)、数组,它也是通过Obeservable读取每个元素然后发出事件。

下面的代码,在空间content上写下3行字:


I have 烂剧本

I have 小鲜肉

啊 小时代


 List<String> list = new ArrayList<>();
        list.add("I have 烂剧本 \n");
        list.add("I have 小鲜肉 \n");
        list.add("阿 小时代\n");

        Observable.from(list)
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        content.setText(fromContentStr.toString());
                        unsubscribe();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d("thm", "onNext s = "+s);
                        fromContentStr.append(s);
                    }
                });
    }



1.3 just

just和from类似,它依次把每个参数作为事件发出去,最多可以有10个参数。


下面的代码在空间content上写下3行字:

I have LOL

I have 路由器

啊 杨教授又多一病例

    Observable.just("I have LOL\n", "I have 路由器\n", "啊 杨教授又多一病例\n")
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        content.setText(fromContentStr.toString());
                        unsubscribe();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d("thm", "onNext s = "+s);
                        fromContentStr.append(s);
                    }
                });


1.4 Subject

Subject是Observable和Observer的集合体,继承了Observable,实现了Observer,

即它即是观察者,也是被观察者。

 Subject subject = PublishSubject.create();
        subject.subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Object o) {

            }
        });
        subject.onNext(new Object());

1.5 subscribe() 订阅方法。只有调用了订阅后,Observable才会开发发送事件,如下的onSubscribe.call()

public Subscription subscribe(Subscriber subscriber) {
    subscriber.onStart();
    onSubscribe.call(subscriber);
    return subscriber;
}
onStart是一个可选方法,默认的实现为空。

可以重写onStart来做一些诸如统计、初始化、打日志之类的事情。

2.1 filter

顾名思义,filter的作用就是过滤,事实也的确如此。

Filters items emitted by an Observable by only emitting those that satisfy a specified predicate. 
return an Observable that emits only those items emitted by the source Observable that the filter
evaluates as {@code true}
筛出根据predicate条件判断为true的项

下面的代码过滤掉原始Observable中的奇数项。

Integer ints[] = {1,2,3,4,5,6,7,8,9,10};

Observable.from(ints)
                .filter(new Func1<Integer, Boolean>() {
                    @Override
                    public Boolean call(Integer ints) {
                        return ints%2 == 0;
                    }
                })
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                        Log.d("thread", "testFilter onCompleted"+Thread.currentThread());
                        content.setText(fromContentStr.toString());
                        unsubscribe();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d("thread", "testFilter onNext"+Thread.currentThread());
                        fromContentStr.append("filter过滤单数"+integer+"\n");
                    }
                });


2.2 debounce

这个api可以用来防止重复操作。它会过滤掉指定时间内的其它事件。

注意:它是过滤掉前面的,保留最后一个!

If items keep being emitted by the source Observable faster than the timeout then no items
will be emitted by the resulting Observable.
因此,下面的代码是从1,2,3,4,5,6,7,8,9,10中过滤掉偶数项。

Observable.create(new Observable.OnSubscribe<Integer>() {
                    @Override
                    public void call(Subscriber<? super Integer> subscriber) {
                        for (Integer i : ints) {
                            if(i%2==0){
                                try {
                                    Thread.sleep(20);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            subscriber.onNext(i);
                        }
                        subscriber.onCompleted();
                    }
                })
                .debounce(10, TimeUnit.MILLISECONDS)
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {
                        content.setText(fromContentStr.toString());
                        Log.d("thread", "testDebounce onCompleted"+Thread.currentThread());
                        unsubscribe();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d("thm", "testDebounce onError msg = "+e.getMessage());
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d("thread", "testDebounce onNext"+Thread.currentThread());
                        fromContentStr.append("debounce过滤双数"+integer+"\n");
                    }
                });

3.指定运行的线程

subscribeOn(Schedulers)来指定事件源的执行线程。

observeOn(Schedulers)来指定观察者的执行线程。

下面是一种最常见的使用场景,在Scheduler.io()中解析数据,在UI线程中更新界面。

基本上所有的后台线程取数据,UI线程做显示的工作都是这样切换线程的。

  RetrofitHelper.getInstance()
                .getGiftList(friendid,userid) // Observable<GiftDataResponse<GiftData<GiftBean>>>
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<GiftDataResponse<GiftData<GiftBean>>>() {
                    @Override
                    public void onCompleted() {
                        LogUtil.d("retorfitHelper getGifts onCompleted");
                    }

                    @Override
                    public void onError(Throwable e) {
                      //do error
                    }

                    @Override
                    public void onNext(GiftDataResponse<GiftData<GiftBean>> httpResponse) {
                       //do sth
                    }
                });
  private AndroidSchedulers() {
        RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();

        Scheduler main = hook.getMainThreadScheduler();
        if (main != null) {
            mainThreadScheduler = main;
        } else {
            mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());
        }
    }
AndroidScheduler.mainThread()就是安卓的UI线程。

Scheduler还有以下获取线程api:

*Scheduler.immediate()   :在当前线程运行,即默认状态

*Scheduler.newThread() :启用一个新线程来执行

*Scheduler.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。

*Scheduler.computation:用于CPU密集型计算,如图像计算。

注意:不要在io中做计算操作,也不要在computation中做io操作。前者会创建不必要的线程,后者会消耗不必要的CPU资源。


4.使用事件转化操作符做嵌套操作

RxJava中主要有3种事件转化操作符,分别为map、flatmap和compse。

4.1 map

map是对象间的转换,比如下面的函数testmap中map是把Integer转成String。

依次把String发出去,最后在content中打印出 “I hava 银子, I have 通宝, 嗯?哼?->同城游”。

 Integer ints[] = {1,2,3,4,5,6,7,8,9,10};
    String s[] = {"I have ","银子, " ,"I have ", "通宝, ","嗯?","哼?", "->", "同城游"};
    private StringBuffer fromContentStr = new StringBuffer();
    private void testMap(){
        Observable.from(ints)
                .map(new Func1<Integer, String>() {
                    @Override
                    public String call(Integer i) {
                        return s[i-1];
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d("thm", "on Next s = "+s);
                        fromContentStr.append(s);
                        content.setText(fromContentStr.toString());
                    }
                });
    }

4.2 flatmap

flatmap是把事件转成一个新的事件源Obervable。

比如下面的代码,通过flatmap将Observable<home>转成Observable<String>,

最后在content上打印出

dad, mom, me

dad, mom, me, brother

    home homes[] = {new home(new String[]{"dad, ", "mom, ", "me\n"}), new home(new String[]{"dad, ", "mom, ", "me, ", "brother\n"})};
    private void testFlatmap(){
        Observable.from(homes)
                .flatMap(new Func1<home, Observable<String>>() {
                    @Override
                    public Observable<String> call(home home) {
                        return Observable.from(home.members);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        content.setText(fromContentStr.toString());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        fromContentStr.append(s);
                    }
                });
    } 
    
    class home{
        String members[];
        public home(String s[]){
            members = s;
        }
    }

结语


这里是我认为RxJava中最常用的api的使用demo。

打算下一篇中总结一下Rx中不是特别常用的那些api,以及配合Retrofit进行网络请求的使用。

作者:u014137988 发表于2016/12/12 20:37:25 原文链接
阅读:48 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>