RxJava1.0用户指南

目录

1. Rxjava简介

Rxjava是什么?简单来说就是一个可以实现异步操作的库。如果是没有接触过Rxjava可以直接使用RxJava2.0,并不会有任何问题。如果是已经在用RxJava1.0或者项目当中已经使用了RxJava1.0那就只能一条路走到黑了。我就是属于后者。 相比于AsyncTask、Handler,RxJava代码更显得优雅简介,调理清晰,随着产品逻辑复杂度的增加,也依然可以使得代码非常简介。rxjava的异步实现是通过一种扩展的观察者模式来实现的,先来简单了解一下观察者模式。

1.1 观察者模式

观察者模:定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态时,所有依赖于它的对象都会得到通知并被自动更新。 触发场景

  • 事件关联场景,需要注意关联行为是不可拆分的,不是简单地“组合”关系。
  • 事件多级触发的场景。
  • 跨系统的消息处理,如消息队列、事件总线等处理机制。

在整个观察者模式中一共有四个角色:Subject(抽象主题、抽象被观察者)、Concrete Subject(具体主题、具体被观察者)、Observer(抽象观察者)以及ConcreteObserver(具体观察者)。四个角色关系如下:

  • Subject(抽象主题、抽象被观察者):抽象主题把所有被观察者对象保存到一个集合当中,并提供一个接口,可以增加、删除和更新观察者对象。
  • ConcreteSubject(具体主题、具体被观察者):将有关状态存入具体观察者对象,在具体主题的内部状态发生时改变,给所有注册过的观察者发出通知。
  • Observer(抽象观察者):观察者的抽象类,定义更新接口,使得被观察者可以在得到主题的时候更新自己。
  • ConcreteObserver(具体观察者):实现抽象观察者定义的更新接口,以便主题的状态发生变化时更新自身状态。

我们用一个具体的场景来体会一下。 说,两国交战,有一只队弓箭手A在要进行埋伏。弓箭手部队拆分为4队A1、A2、A3,有指挥者发布命令,当收到命令时所有小队进行射击。这个时候指挥者就是被观察者而每一队弓箭手就是观察者,代码实现如下。 被观察者代码如下

/**
 * 定义被观察者抽象类
 */
public abstract class Subject<T> {
    //创建观察者集合
    List<Observer> mList = new ArrayList<Observer>();
    //添加观察者
    public void add(Observer observer) {
        mList.add(observer);
    }
    //删除观察者
    public void remove(Observer observer) {
        if(mList!=null&&mList.contains(observer)){
            mList.remove(observer);
        }
    }
    //更新
    public abstract void notifyObserver(T t);
}

/**
 * 被观察者具体实现
 */
public class ConcreteSubject<T> extends Subject<T> {

    @Override
    public void notifyObserver(T t) {
        for(Observer observer:mList){
            observer.update(t);
        }
    }
}
复制代码

观察者代码如下

/**
 * 观察者抽象接口
 */
public interface Observer<T> {

    void update(T t);
}


/**
 * 观察者具体实现
 */
public abstract class ConcreteObserver<T> implements Observer<T> {
    String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    public String getName(){
        return name;
    }
}
复制代码

这里我的观察者是一个抽象类,实现方式类似于Rxjava的实现方式。

Main当中的代码调用

//update类具体实现创建observer1、observer2、observer3三个观察者
    Observer<String> observer1 = new ConcreteObserver<String>("弓箭手A1队") {
        @Override
        public void update(String s) {
            Log.d("Observer1", getName() + "收到命令:" + s);
        }
    };
    Observer<String> observer2 = new ConcreteObserver<String>("弓箭手A2队") {

        @Override
        public void update(String s) {
            Log.d("Observer2", getName() + "收到命令:" + s);
        }
    };
    Observer<String> observer3 = new ConcreteObserver<String>("弓箭手A3队") {
        @Override
        public void update(String s) {
            Log.d("Observer3", getName() + "收到命令:" + s);
        }
    };
//设置被观察者与观察者之间关联
    Subject<String> subject = new ConcreteSubject<String>();
    subject.add(observer1);
    subject.add(observer2);
    subject.add(observer3);
//被观察者发送信息
    subject.notifyObserver("射杀骑白马者!!");
复制代码

打印日志

D/Observer1: 弓箭手A1队收到命令:射杀骑白马者!!

D/Observer2: 弓箭手A2队收到命令:射杀骑白马者!!

D/Observer3: 弓箭手A3队收到命令:射杀骑白马者!!

1.2 Rxjava中的观察者模式

在Rxjava当中有四个基本概念,除了观察者Observer/Subscriber和被观察者Observable之外,ha存在订阅subscribe以及事件

被观察者Observable与观察者Observer/Subscriber产生关联的方法就是subscribe,即事件订阅,当开始订阅时,被观察者Observable便开始发送事件。对于事件,Rxjava定义了三种事件类型:

  • onNext():普通的事件,用于一般的事件发送。
  • onCompleted(): 完成事件,当不再有新的onNext()事件时调用onCompleted方法作为整个事件队列结束的标志,在一个事件队列当中可以有多个onCompleted方法,但是只能触发一次,一旦触发之后,后续的事件会继续发送,但是观察者将不会接受事件。
  • onError(): 事件队列异常。在事件处理过程中出现异常时,onError()会被触发,同事队列自动终止,与onCompleted()方法相同,onError事件也可以存在多个,但是只会触发一次。

最为关键的是onCompleteonError存在互斥的关系, 两个方法可以同时存在于事件队列当中,但是一旦触发其中一个方法之后,后续将不再接收事件。

2.基本实现

RxJava的实现非常简单

首先要在Android studio中配置gradle

implementation 'io.reactivex:rxjava:1.1.6'
implementation 'io.reactivex:rxandroid:1.2.1'
复制代码

RxAndroid是RxJava在Android平台的一些扩展,包含了一些能够简化Android开发的工具。(implementation与compile用法基本相同,有兴趣的可以去了解一下两者的差别)

2.1 创建观察者

观察者Observer决定了事件触发的时候将有怎样的行为。

Observer<String> observer = new Observer<String>() {
        //被观察者调用onCompleted时触发
        @Override
        public void onCompleted() {
            Log.d(TAG,"onCompleted");
        }
        //被观察者调用onError时触发
        @Override
        public void onError(Throwable e) {
            Log.d(TAG,"onError");
        }
        //被观察者调用onNext时触发
        @Override
        public void onNext(String s) {
            Log.d(TAG,"onNext");
        }
    };
复制代码

另外一个观察者就是Subscriber,而实际上在调用subscribe方法订阅的时候也是把Observer转换为了Subscriber处理的,后文我们会在RxJava的代码中提到,先来看一看Subscriber的实现,与Observer基本一致。

Subscriber<String> subscriber = new Subscriber<String>() {
        //新增onStart方法,用来做一些初始化操作
        @Override
        public void onStart() {
            super.onStart();
        }

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

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

        @Override
        public void onNext(String s) {
            Log.d(TAG,"onNext");
        }
    };
复制代码

这里新增加了onStart方法,这个方法会在事件开始发送前调用,实际应用中我们可以在这个方法当中做一些初始化的操作,但是这个方法一般只会在subscribe发生的线程执行(使用doOnSubscribe()方法可以改变准备线程)。

另一个不同就是Subscriber实现了另一个接口Subscription,它里面提供了两个方法unsubscribe()和isUnsubscribed():

  • unsubscribe:用于取消订阅,因为RxJava当中的操作可能会引起内存泄漏,在合适的地方调用该方法可以避免这个问题。
  • isUnsubscribed:用于判断订阅是否被取消。

2.2 创建被观察者

它决定什么时候触发事件以及触发怎样的事件。RxJava提供了多种构建被观察者的方式,也提供了很多特殊的被观察者,这里介绍一些比较常用的方法。

使用create创建被观察者

Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            Log.d(TAG,"Observable Test");
            //定义事件队列
            subscriber.onNext("aaaa");
            subscriber.onCompleted();
        }
    });
复制代码

使用create( )创建Observable最基本的创建方式。可以看到,这里传入了一个 Observable.OnSubscribe对象作为参数,当 Observable被订阅的时候,Observable.OnSubscribe的call()方法会自动被调用,事件序列就会依照设定依次触发。这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。

除了create方法之外,还存在其他的常用的构建方式。

just()

使用just( ),将为你创建一个Observable并自动为你调用onNext( )发射数据。通过just( )方式 直接触发onNext(),just中传递的参数将直接在Observer的onNext()方法中接收到。

Observable<String> observable =  Observable.just("hello");
observable.subscribe(subscriber);
复制代码

输出log

 D/MainActivity: onNext
 D/MainActivity: onCompleted
复制代码

from()

from()方法将传入的数组Iterable拆分成具体对象后,自动调用onNext方法依次发送,再发送结束后发送onCompleted结束整个事件。

//定义要发送的事件集合
    List<String> mList = new ArrayList<String>();
    mList.add("aaaa");
    mList.add("bbbb");
    mList.add("cccc");
    mList.add("dddd");
    //定义Observable
    Observable<String> observable = Observable.from(mList);
    //进行订阅,开始发送事件
    observable.subscribe(subscriber);
复制代码
D/MainActivity: onNextaaaa
D/MainActivity: onNextbbbb
D/MainActivity: onNextcccc
D/MainActivity: onNextdddd
D/MainActivity: onCompleted
复制代码

defer()

通过defer()方法创建Observable,当观察者订阅时,才创建Observable,并且针对每个观察者创建都是一个新的Observable。以何种方式创建这个Observable对象,当满足回调条件后,就会进行相应的回调。还是通过代码来看。

    //定义一个被观察者
    Observable<String> observable = Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable<String> call() {

                Observable<String> mObservable = Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("事件订阅开始");
                    }
                });
                return mObservable;
            }
        });
        //订阅事件1,没产生一个订阅就会生成一个新的observable对象
        observable.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d(TAG,"观察者2订阅事件    "+s);
            }
        });
        //订阅事件2,没产生一个订阅就会生成一个新的observable对象
        observable.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d(TAG,"观察者1订阅事件    "+s);
            }
        });
复制代码

打印输出运行结果

D/MainActivity: 观察者2订阅事件    事件订阅开始
D/MainActivity: 观察者1订阅事件    事件订阅开始
复制代码

使用defer()方法,每当产生新的订阅事件时都会生成一个新的mObservable对象。

这里用到了不完整定义的回调Action,它就相当于我们之前定义的subscriber,但是其只针对onNext事件做处理,后续我们介绍subscribe()时再详细介绍。

interval()

创建一个按固定时间间隔发射整数序列的Observable,可用作定时器。即按照固定时长调用onNext()方法。

    Observable<Long> observable = Observable.interval(1, TimeUnit.SECONDS);
        observable.subscribe(new Action1<Long>() {
            @Override
            public void call(Long aLong) {
                Log.d(TAG,"订阅时长为"+aLong);
            }
        });
复制代码

输出结果日志:

D/MainActivity: 订阅时长为0
D/MainActivity: 订阅时长为1
D/MainActivity: 订阅时长为2
D/MainActivity: 订阅时长为3
D/MainActivity: 订阅时长为4
D/MainActivity: 订阅时长为5
D/MainActivity: 订阅时长为6
......
复制代码

每隔一秒发送一个事件交给观察者处理。

timer()

该方法可以在一定延迟之后发送特定事件。

//定义被观察者,在2000毫秒后开始发送事件
    Observable<Long> observable = Observable.timer(2000,TimeUnit.MILLISECONDS);
        Subscriber<Long> subscriber = new Subscriber<Long>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Long aLong) {
                Log.d(TAG,"收到事件啦");
            }
        };
        Log.d(TAG,"开始订阅发送事件");
        observable.subscribe(subscriber);
复制代码

输出日志

16:09:38.524 D/MainActivity: 开始订阅发送事件
16:09:40.524 D/MainActivity: 收到事件啦
复制代码

可以看到在订阅之后,过了2000毫秒observable开始发送事件。

到这里我们创建了观察者Observable与观察者Observer/Subscriber,只到这一步我们会产生很多疑问:interval发送事件如何取消订阅、上面提到的Action到底什么时候会用到,为什么Subscriber的start方法只能在默认线程调用等等问题。这个时候就该到我们的subscribe登场了。

2.3 Subscribe订阅

创建完ObservableObserver/Subscriber,使用subscribe那我们整个订阅过程就就完成了,在上面的代码也有提到,整个调用方式如下

observable.subscribe(subscriber);
复制代码

我们来简单看一下subscribe()方法的源码。

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
        subscriber.onStart();
        observable.onSubscribe.call(subscriber);
        return Subscription;
    }
复制代码

这里提出了关键的流程代码,结合订阅的调用过程我们分析整个订阅流程。

  • 首先是传进来的两个参数SubscriberObservable分别对应我们调用时的subscriberobservable
  • 订阅开始后,首先执行的是subscriber.onStart()方法,也就是我们观察者的onStart方法,这也就解释了为什么onStart方法只可以在默认线程当中执行,因为我们指定线程只可以指定observable所对应线程以及observable对应直属下级Subscriber(好吧这里又是一个坑,后文我们会做解释)所在线程。
  • 接下来调用observable当中的onSubscribe.call方法,我们的整个事件序列就定义在这里,调用call方法开始发送事件。
  • 返回值Subscription,之前在介绍观察者Subscriber时我们有提到,Subscriber实现了这个接口,用于提供解除订阅以及判断订阅是否连接的方法,在订阅完成之后返回Subscription供外部调用。

不完整定义回调

从上图可以看出,subscribe方法的参数除了 SubscriberObserver之外,还有Action类,这就是将要介绍的 不完整定义回调

        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("aaaaa");
                subscriber.onError(new NullPointerException());
            }
        });
        //只对事件序列中的onNext做出响应
        Action1<String> action1 = new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d(TAG,"action1--->onNext  "+s);
            }
        };
        //只对事件序列中的onError做出响应
        Action1<Throwable> action11 = new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                Log.d(TAG,"action11--->onError  "+throwable.getMessage());
            }
        };
        //只对事件序列中的onCompleted做出响应
        Action0 action0 = new Action0() {
            @Override
            public void call() {
                Log.d(TAG,"action11--->onCompleted  ");
            }
        };
        //订阅事件,只处理onNext事件
        observable.subscribe(action1);
        //订阅事件,只处理onNext和onError事件
        observable.subscribe(action1,action11);
        //订阅事件,处理onNext、onError和onCompleted事件
        observable.subscribe(action1,action11,action0);
复制代码

2.4 RxJava链式调用

在实际应用中,我们可以采用链式调用的方式把上述步骤串联起来,从而使得代码结构更加简洁,优雅。

//定义将要发射的数组
    String[] strs = {"1", "2", "3", "4", "5"};
    //from操作符可以把数组当中的数据逐条发送出去
        Observable.from(strs)
        //调用flatMap操作符把String类型转换为新的Observable<String>并开始发送事件后文会进行介绍。
            .flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String s) {
                Log.d("testRX---map",s);
                //需要把String类型转换成的Observable对象
                return Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("test");
                    }
                });
            }
        }).subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                //处理完成事件
            }
            @Override
            public void onError(Throwable e) {
                //处理error事件
            }
            @Override
            public void onNext(String s) {
                //处理普通的onNext事件
            }
        });
复制代码

在这个例子中用到了变换操作符flatMap,在实际应用中也会经常用到,下面我们详细介绍一下。

3. 变换操作符

变换操作符的作用是对Observable发射的数据按照一定规则做一些变换操作,然后将变换后的数据发射出去。变换操作符有map,flatMap,switchMap,flatMapIterable,buffer,groupBy等。

map

map操作符就是通过制定一个Func1对象,将原Observable对象转换为另一个Observable对象并发射。

        //定义初始事件序列数组
        Integer[] ints = {1, 2, 3};
        //调用from逐个发射数据
        //map方法把Intger类型转换为String类型
        Observable.from(ints).map(new Func1<Integer, String>() {
            @Override
            public String call(Integer i) {
                //对Integer数据进行处理,转换成String类型返回
                return i + "号玩家";
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d(TAG,s+"加入游戏");
            }
        });
复制代码

运行输出结果:

D/MainActivity: 1号玩家加入游戏
D/MainActivity: 2号玩家加入游戏
D/MainActivity: 3号玩家加入游戏
复制代码

这里就比较有意思了,map方法怎么就把一种数据类型转换成了另一种数据类型呢 我们看一下map的源码

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
    return lift(new OperatorMap<T, R>(func));
}

//这里新建了一个Operator对象,核心功能代码如下
public final class OperatorMap<T, R> implements Operator<R, T> {
    final Func1<? super T, ? extends R> transformer;

    public OperatorMap(Func1<? super T, ? extends R> transformer) {
        this.transformer = transformer;
    }

    @Override
    public Subscriber<? super T> call(final Subscriber<? super R> o) {
        MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
        o.add(parent);
        return parent;
    }
}

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
    }
复制代码

这里新建一个newSubscriber并与原observable订阅的Subscriber关联起来,left方法本身也返回一个新建的被观察者newObservable。由此变为,当产生事件订阅时,实际上是newObservable订阅了事件,之后而通知原observable开始发送事件,原observable发送的事件发送向newSubscriber,再发送给Subscriber

整个事件的流程变化如下:

flatMap

flatMap也是用来做类型转换,不同于map的是,flatMap转换后得到的是一个Observable对象。代码实现如下:

//interval方法创建Observable对象,每隔1秒发送一个事件
//经过flatMap方法变化,将long类型的事件变换为一个新的Observable对象发射出去
subscription = Observable.interval(1, TimeUnit.SECONDS).flatMap(new Func1<Long, Observable<String>>() {
            @Override
            public Observable<String> call(final Long aLong) {
                return Observable.create(new Observable.OnSubscribe<String>(){
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        Log.d("testRX---next","test"+aLong);
                        subscriber.onNext(aLong+"");
                    }
                });
            }
            //定义Subscriber对变换后的事件进行接收
        }).subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, "onCompleted");
            }

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

            @Override
            public void onNext(String s) {
                Log.d(TAG, "onNext" + s);
            }
        });
复制代码

打印输出结果:

D/testRX---next: test0
D/MainActivity: onNext0
D/testRX---next: test1
D/MainActivity: onNext1
D/testRX---next: test2
D/MainActivity: onNext2
D/MainActivity: onNext3
......
复制代码

flatMap的原理比较复杂,我们还是通过源码来分析

public final <R> Observable<R> flatMap(Func1<? super T, ? extends Observable<? extends R>> func) {
    if (getClass() == ScalarSynchronousObservable.class) {
        return ((ScalarSynchronousObservable<T>)this).scalarFlatMap(func);
    }
    return merge(map(func));
}
复制代码

首先在这里它调用了map方法,在前面我们分析过,map方法会生成一个新的Observable对象,并改变事件的订阅顺序,接下来执行到merge方法,merge方法做了什么呢

 public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
    }
    
public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {
    
    public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
        this.parent = parent;
        this.operator = operator;
    }

    @Override
    public void call(Subscriber<? super R> o) {
       Subscriber<? super T> st = hook.onLift(operator).call(o);
                 // new Subscriber created and being subscribed with so 'onStart' it
        st.onStart();
        parent.call(st);
    }
}
    
复制代码

这里会把每一个创建出来的 Observable 发送的事件,都被汇入同一个 Observable ,这个 Observable 负责将这些事件统一交给 Subscriber 的回调方法。

buffer

buffer操作符将源Observable变换为一个新的Observable,这个新的Observable每次发射一组列表值而不是一个一个发射。和buffer操作类似的还有window操作符,只不过window操作符发射的是Observable而不是数据列表。

Observale.just(1,2,3,4,5,6).buffer(3).subscribe(new Action1<List<Integer>>() {
    @Override
    public void call(List<Integer> integers){
        for(Integer integer:integers){
            Log.d(TAG,"buffer"+integer);
        }
  Log.d(TAG,"---------");
    }
});
复制代码

输出日志:

D/MainActivity: buffer1
D/MainActivity: buffer2
D/MainActivity: buffer3
D/MainActivity: ---------
D/MainActivity: buffer4
D/MainActivity: buffer5
D/MainActivity: buffer6
D/MainActivity: ---------
复制代码

fliter

filter()操作符根据test()方法中,根据自己想过滤的数据加入相应的逻辑判断,返回true则表示数据满足条件,返回false则表示数据需要被过滤。最后过滤出的数据将加入到新的Observable对象中,方便传递给Observer想要的数据形式。

Observable.just(1,2,3,4,5,6).filter(new Func1<Integer, Boolean>() {
    @Override
    public Boolean call(@NonNull Integer integer){
        if(integer > 3){
            return true;
        }
        return false;
    }
}).subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer){
        Log.d(TAG,integer+"");
    }
});
复制代码

输出结果

D/MainActivity: onSubscribe
D/MainActivity: onNext
D/MainActivity: Hello World!
D/MainActivity: 4
D/MainActivity: 5
D/MainActivity: 6
复制代码

4. 线程调度

默认情况下,在哪个线程调subscribe(),就会在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,则需要 Scheduler (调度器)

在RxJava 中,Scheduler,相当于线程控制器,RxJava 通过它来指定每一段代码应该运行在什么样的线程。RxJava 已经内置了几个 Scheduler ,它们已经适合大多数的使用场景。

Scheduler 的 API

  • 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 主线程运行。

有了这几个 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。

  • subscribeOn(): 指定Observable(被观察者)所在的线程,或者叫做事件产生的线程。
  • observeOn(): 指定 Observer(观察者)所运行在的线程,或者叫做事件消费的线程。 实例如下:
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                Log.d(TAG, Thread.currentThread().getName());
                subscriber.onNext("aaaa");
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {

                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "onCompleted");
                        Log.d(TAG, Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(TAG, "onNext " + s);
                    }
                });
复制代码

输出日志:

D/MainActivity: RxIoScheduler-2
D/MainActivity: onNext aaaa
D/MainActivity: onCompleted
D/MainActivity: main
复制代码

总结

RxJava在刚刚接触的时候使用起来会觉得比较别扭,主要是与java的方式存在一些差异,使用一段时间之后就会产生“RxJava太好用了”的感觉。一些原理性的东西这里介绍的比较简单,大家有兴趣的可以看一下给 Android 开发者的 RxJava 详解,介绍的很详细。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值