RxJava 1.2.1主要API的使用Demo

来源:互联网 发布:js字符串分割成数组 编辑:程序博客网 时间:2024/06/03 19:49

前言:

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 filterevaluates 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 itemswill 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进行网络请求的使用。

0 0
原创粉丝点击