RxJava

整理自扔物线的RxJava详解 http://gank.io/post/560e15be2dca930e00da1083

基本流程

就是创建Observable和Subscriber,然后调用Observable的subscribe方法绑定在一起

observable.subscribe(subscriber);

Observer

创建观察者,指定事件触发时的行为(比如网络请求回调)。实际上Observer会被转换成Subscriber来使用。在Observable调用subscribe方法后,Observable中的OnSubscribe会调用Observer的一系列方法

new Observer<String>() {
  @Override
  public void onCompleted() {
     Log.e("TAG", "onCompleted");
  }

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

  @Override
  public void onNext(String s) {
     Log.e("TAG", "onNext:" + s);
  }
};

也可以直接创建Subscriber,相比于Observer,Subscriber增加了onStart和unsubscribe两个方法方法。
onStart方法在Observable调用subscribe方法后,而且在OnSubscribe实现类的call方法之前调用。因此可以用来进行一些准备工作。但是由于onStart执行在subscribe所发生线程,实际使用中subscribe几乎都在后台调用,因此如果要在主线程中进行一些onNext之前的操作,需要调用doOnSubscribe方法来实现。
unsubscribe方法是Subscriber所实现的Subscription接口所提供的,可以将Observable调用subscribe方法所持有的Subscriber引用释放掉,不用时及时释放可以避免内存泄露。一般调用unsubscribe方法之前,可以先调用isUnsubscribed方法判断当前状态。

Subscriber<String> subscriber = new Subscriber<String>() {
    @Override
    public void onStart() {
         Log.e("TAG", "onStart---" + Thread.currentThread().getName());
    }

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

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

   @Override
   public void onNext(String s) {
        Log.e("TAG", "onNext:" + s + Thread.currentThread().getName());
   }
};

Subscriber的快捷创建方式

// 因为Action1接口只定义了单个参数的方法,所以可以用来定义为onNext或者onError
Action1<String> onNextAction = new Action1<String>() { 
    @Override
    public void call(String s) {
        Log.e("TAG", "Action1--onNextAction: " + s);
    }
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
    @Override
    public void call(Throwable throwable) {
        Log.e("TAG", "Action1--onErrorAction: ");
    }
};
Action0 onCompletedAction = new Action0() { // 而Action0接口只定义了无参方法,可以用来定义为onCompleted
    @Override
    public void call() {
        Log.e("TAG", "Action0--onCompletedAction: ");
    }
};
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);

Observable

创建Observable,即观察者,它决定触发事件的时机以及规则。基本创建方式是调用Observable的静态方法create,传入Observable的OnSubscribe的实现类,当Observable调用subscribe方法后就会调用OnSubscribe的call方法向Subscriber传递消息

Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        Log.e("TAG", "call---" + Thread.currentThread().getName());
        subscriber.onNext("first");
        subscriber.onNext("second");
        subscriber.onNext("third");
        subscriber.onCompleted();
    }
});

Observable的快捷创建方式,等价于上面那种方式,只能创建onNext事件

        final Observable<String> just = Observable.just("just--first", "just--second", "just--third");
        final Observable<String> from = Observable.from(new String[]{"from--first", "from--second", "from--third"});
        from.subscribe(subscriber);
        just.subscribe(subscriber);

subscribe方法

该方法会首先调用Subscriber的onStart方法,然后才调用OnSubscriber的call方法执行定义的事件序列,返回参数是subscription对象,可以用来调用unsuscribe方法解除绑定,避免内存泄露

final Subscription subscription = observable.subscribe(subscriber);

subscribe()的源码的基本实现:

public Subscription subscribe(Subscriber subscriber) {
    subscriber.onStart();  // 调用绑定的subscriber的onStart方法
    onSubscribe.call(subscriber);  // 将绑定的subscriber传入到Observable.OnSubscribe实现类中调用
    return subscriber;     // 返回绑定的subscriber
}

简单示例

int drawableRes = ...;
ImageView imageView = ...;
Observable.create(new OnSubscribe<Drawable>() {
    @Override
    public void call(Subscriber<? super Drawable> subscriber) {
        Drawable drawable = getResources().getDrawable(drawableRes));
        subscriber.onNext(drawable);
        subscriber.onCompleted();
    }
}).subscribe(new Observer<Drawable>() {
    @Override
    public void onNext(Drawable drawable) {
        imageView.setImageDrawable(drawable);
    }

    @Override
    public void onCompleted() {
    }

    @Override
    public void onError(Throwable e) {
        Toast.makeText(activity, "Error!", Toast.LENGTH_SHORT).show();
    }
});

线程切换

RxJava默认的事件产生和消费都是在主线程。而不指定线程情况下,遵循线程一致原则,即哪个线程调用subscribe,就在哪个线程产生事件,同时也在那个线程消费事件。需要切换线程的话需要用到Schedulers。Observable可以调用subscribeOn方法指定subscribe方法发生的线程,也就是Observable.OnSubscribe的call方法运行的线程,即生产线程。还有调用observeOn方法指定subscriber运行的线程,即消费的线程。
- 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 主线程运行。

示例

Observable.just(1, 2, 3, 4)
    .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
    .observeOn(AndroidSchedulers.mainThread()) // 指定Subscriber 的回调发生在主线程
    .subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer number) {
            Log.d(tag, "number:" + number);
        }
    });

变换

map()

Returns an Observable that applies a specified function to each item emitted by the source Observable and emits the results of these function applications. 对Observable所发送的每个对象应用特定的变换,然后发送
该方法适用于一对一的变换

final ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(new Student("小明", new String[]{"鱼尾纹", "数学"}));
arrayList.add(new Student("小红", new String[]{"政治", "体育"}));
arrayList.add(new Student("小王", new String[]{"音乐", "美食"}));

Observable.from(arrayList)
        .map(new Func1<Student, String>() {
            @Override
            public String call(Student student) {
                return student.getName();
            }
        })
        .subscribe(new Action1<String>() {
             @Override
             public void call(String s) {
                 Log.e("TAG", s);
             }
         });

flatMap()

Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an Observable, and then merging those resulting Observables and emitting the results of this merger. 对初始Observable的每个对象应用变换,变换结果返回一个新的Observable,然后把所有新的Observable合并为一个Observable,也就是所有新生成的Observable都会发送事件,发送的事件都会汇总到结果的Observable当中
该方法可以实现一对多,也就是初始对象包含了多个Observer需要处理的对象

final ArrayList<Student> arrayList = new ArrayList<>();
ArrayList<Course> list = new ArrayList<>();
list.add(new Course("语文"));
list.add(new Course("数学"));
arrayList.add(new Student("小明", list));
list = new ArrayList<>();
list.add(new Course("体育"));
list.add(new Course("美术"));
arrayList.add(new Student("小红", list));
list = new ArrayList<>();
list.add(new Course("音乐"));
list.add(new Course("政治"));
arrayList.add(new Student("小王", list));

Observable.from(arrayList)
        .flatMap(new Func1<Student, Observable<Course>>() {
            @Override
            public Observable<Course> call(Student student) {
                return Observable.from(student.getCourses()); 
                // 新Observable处理的对象是Observer最终需要的对象的集合
            }
        })
        .subscribe(new Action1<Course>() {
            @Override
            public void call(Course course) {
                Log.e("TAG", course.getName());
            }
        });

flatMap实际应用中可以使用在嵌套的网络请求

networkClient.token() // 返回 Observable<String>,在订阅时请求 token,并在响应后发送 token
    .flatMap(new Func1<String, Observable<Messages>>() {
        @Override
        public Observable<Messages> call(String token) {
            // 返回 Observable<Messages>,在订阅时请求消息列表,并在响应后发送请求到的消息列表
                return networkClient.messages();// 可以在这里添加Retrofit的请求消息列表方法
        }
    })
    .subscribe(new Action1<Messages>() {
        @Override
        public void call(Messages messages) {
            // 处理显示消息列表
            showMessages(messages);
        }
    });

throttleFirst():

.throttleFirst(500, TimeUnit.MILLISECONDS) // 设置防抖间隔为 500ms,可以避免按钮防止短时间内重复点击

变换原理lift()

// lift()源码中的基本实现代码
public <R> Observable<R> lift(Operator<? extends R, ? super T> operator) {
    return Observable.create(new OnSubscribe<R>() {  // 返回的是Observable<R>类型
        @Override
        public void call(Subscriber subscriber) {
            Subscriber newSubscriber = operator.call(subscriber);
            newSubscriber.onStart();
            onSubscribe.call(newSubscriber);
        }
    });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值