首页 > 代码库 > Rxjava上手

Rxjava上手

使用Rxjava框架,我个人觉得最大的好处就是能够很方便的在各个线程当中进行切换,而且代码还能保持很优雅。

在代码里面加上以下内容,便可以使用了。

compile ‘io.reactivex:rxjava:1.0.14‘
compile ‘io.reactivex:rxandroid:1.0.1‘

只需要掌握以下三部分内容,便可以很方便的使用Rxjava框架了。

1.发射器和接收器

首先来看一下最常规的写法:

//接收器
Observer<String> observer = new Observer<String>() {
    @Override
    public void onCompleted() {
        Log.i("Rx","调用了onCompleted");
    }

    @Override
    public void one rror(Throwable e) {
        Log.i("Rx","调用了onError");
    }

    @Override
    public void onNext(String s) {
        Log.i("Rx","调用了onNext ,"+s);
    }
};

//发射器
Observable observable = Observable.create(new Observable.OnSubscribe<String>(){

    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("hello");//发射
        subscriber.onNext("hi");
        subscriber.onNext("Aloha");
        subscriber.onCompleted();
    }
});

observable.subscribe(observer);//关联发射器和接收器

执行这段代码可以得到如下结果:

技术分享

在这段代码中,发射器分别发送了“hello”、“hi”、“Aloha”给接收器,

接收器的onNext函数接收到了数据,并打印出来。

在上一段代码当中,接收器当中有onError、onComplete函数,

如果你并不关心这些,那么可以使用Action接口,具体如下:

//发射器
Observable observable = Observable.create(new Observable.OnSubscribe<String>(){

    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("hello");
        subscriber.onNext("world!");
    }
});

observable.subscribe(new Action1<String>() {//接收器
    @Override
    public void call(String str) {
        Log.i("Rx","调用了call ,"+str);
    }
});

代码执行结果如下:

技术分享

除了采用create函数创建发射器外,还有其他的方式,以下为几种常见的创建方式:

a.使用just( ),将为你创建一个Observable并自动为你调用onNext( )发射数据:

justObservable = Observable.just("just1","just2");//依次发送"just1"和"just2"

b.使用from( ),遍历集合,发送每个item:

List<String> list = new ArrayList<>();
list.add("from1");
list.add("from2");
list.add("from3");
fromObservable = Observable.from(list);  //遍历list 每次发送一个
/** 注意,just()方法也可以传list,但是发送的是整个list对象,而from()发送的是list的一个item** /

还有一些其他的创建方式,具体可以参见这篇博客

http://www.jianshu.com/p/5e93c9101dc5

2.操作符

Rxjava框架当中有很多操作符,以下介绍两个最常用的操作符。

Map:能将一个对象转换成为另外一个对象。

如下所示,将路径字符串转变成为图片

Observable.just("path").map(new Func1<String, Bitmap>() {//发射器发送path,map将path变成bitmap
    @Override
    public Bitmap call(String s) {
        Bitmap bitmap = BitmapFactory.decodeFile(s);
        return bitmap;
    }
}).subscribe(new Action1<Bitmap>() {//接收器接收bitmap
    @Override
    public void call(Bitmap bitmap) {
        image.setImageBitmap(bitmap);
    }
});

flatMap:能将一个发射器转变成为另外一个发射器

举例说明,一个班级包含有多个学生

public class ClassRoom {
    public String name;
    public List<Student> stuList;

    public ClassRoom(){
        stuList = new ArrayList<>();
    }
}

以下代码将一个ClassRoom的发射器转变成为多个Student发射器

Observable.from(list).flatMap(new Func1<ClassRoom, Observable<Student>>() {//将ClassRoom发射器转变成为Student发射器
    @Override
    public Observable<Student> call(ClassRoom classRoom) {
        return Observable.from(classRoom.stuList);
    }
}) .subscribe(new Action1<Student>() {//接收器接收Student
    @Override
    public void call(Student student) {
        Log.i("Rx","调用了call "+student.name);
    }
});

3.调度

个人认为调度是Rxjava里面最好用的一个功能,能够让代码变得很优雅,具体功能如下:

 

调度器类型

用途

Schedulers.computation( )

用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量

Schedulers.from(executor)

使用指定的Executor作为调度器

Schedulers.immediate( )

在当前线程立即开始执行任务

Schedulers.io( )

用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器

Schedulers.newThread( )

为每个任务创建一个新线程

Schedulers.trampoline( )

当其它排队的任务完成后,在当前线程排队开始执行

AndroidSchedulers.mainThread()

此调度器为RxAndroid特有,顾名思义,运行在Android UI线程上

举例:

从文件路径当中读取图片然后显示。

由于读取文件比较耗时,所以要新建线程来读取,

读取完之后,必须在UI线程当中显示,所以通常的代码如下

new Thread(new Runnable() {
    @Override
    public void run() {
        final Bitmap bitmap = BitmapFactory.decodeFile("path");//新建线程,从路径当中读取图片;

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                image.setImageBitmap(bitmap);//UI线程,将读取的图片显示
            }
        });

    }
}).start();

如果逻辑稍微复杂一点,代码就会异常臃肿,而使用Rxjava会使代码很优雅

Observable.just("path").map(new Func1<String, Bitmap>() {//发射器
    @Override
    public Bitmap call(String s) {
        Bitmap bitmap = BitmapFactory.decodeFile(s);
        return bitmap;
    }
}).subscribeOn(Schedulers.io())//指定发射器在IO线程
  .observeOn(AndroidSchedulers.mainThread())//指定接收器在UI线程
  .subscribe(new Action1<Bitmap>() {//接收器
    @Override
    public void call(Bitmap bitmap) {
        image.setImageBitmap(bitmap);
    }
});

只需要使用subscribeOn指定发射器线程,observeOn指定接收器线程,这样便可以方便的在各个线程之间进行切换了。

参考博客:http://www.jianshu.com/p/5e93c9101dc5

                    http://gank.io/post/560e15be2dca930e00da1083

Rxjava上手