设为首页 加入收藏

TOP

Android开发学习之路-Android中使用RxJava(三)
2017-10-13 10:35:51 】 浏览:2421
Tags:Android 开发 习之 -Android 使用 RxJava
rride
6 public void call(Student student) { 7 for (int i = 0; i < student.courses.length; i++) { 8 Log.d(TAG, "score = " + student.courses[i].score); 9 } 10 } 11 });

就是在接收端接收到一个Student类型的值,再使用for循环打印对应属性的值。

但是如果我们不想使用for循环,而是希望直接再接收端就可以处理对应的成绩,就要用到flatmap。代码如下:

 1         Observable.just(s1, s2).flatMap(new Func1<Student, Observable<Course>>() {
 2             @Override
 3             public Observable<Course> call(Student student) {
 4                 return Observable.from(student.courses);
 5             }
 6         }).subscribe(new Action1<Course>() {
 7             @Override
 8             public void call(Course course) {
 9                 Log.d(TAG, "score = " + course.score);
10             }
11         });

※ Observable的泛型改为我们要转换的类型Course,表示我们把两个Student对象的每个Course发送出去。在Func1中的call方法中根据传入的Student对象的courses属性构造一个Observable并返回,RxJava会帮我们把每个Course逐个发送出去,log如下所示:

这里如果你觉得还是不够,你想把每个成绩变成Integer再发送,该怎么做?

我们可以在返回Observable之前再进行一次map转换,这个时候得到的就是Integer了,记得更改Observable对应的泛型为Integer哦,代码如下:

 1         Observable.just(s1, s2).flatMap(new Func1<Student, Observable<Integer>>() {
 2             @Override
 3             public Observable<Integer> call(Student student) {
 4                 return Observable.from(student.courses).map(new Func1<Course, Integer>() {
 5                     @Override
 6                     public Integer call(Course course) {
 7                         return course.score;
 8                     }
 9                 });
10             }
11         }).subscribe(new Action1<Integer>() {
12             @Override
13             public void call(Integer score) {
14                 Log.d(TAG, "score = " + score);
15             }
16         });
View Code

变换操作还有其他一些,可以自行了解尝试。

 

③ 过滤操作

在上面的计时器的例子中我们已经使用了过滤操作,take算是比较简单的过滤了。这里简单介绍一下debounce,它可以让我们过滤掉一段时间内的消息。

设定了debounce之后,在一个消息发送之后的一段时间之内发送的消息将会被过滤抛弃掉。这里没想到更好的例子,原谅我:

1         Observable.interval(1, TimeUnit.SECONDS).debounce(2, TimeUnit.SECONDS)
2                 .subscribe(new Action1<Long>() {
3             @Override
4             public void call(Long aLong) {
5                 Log.d(TAG, "call() called with: aLong = [" + aLong + "]");
6             }
7         });

可以看到我们设置的定时,每隔1s发送一个消息,而又给它设定了debounce为2s,什么意思呢,就是间隔小于2s的消息都被抛弃,所以这段代码没有任何输出。


 

实际上,RxJava还有其他一些操作,这里先忽略。说一些Android开发有关的

我们的异步操作一般是用来进行网络请求的,或者进行耗时操作,那么这个时候肯定不能在主线程中进行,而RxJava的一大优点是,我们可以任意的切换线程,并且,切换起来非常方便。

为了验证所在的线程,我们先编写一个方法来获取当前线程的id:

1     private long getCurrentThreadId() {
2         return Thread.currentThread().getId();
3     }

接着我们先验证一般情况下消息的发送和接收:

 1         Observable.create(new Observable.OnSubscribe<String>() {
 2             @Override
 3             public void call(Subscriber<? super String> subscriber) {
 4                 Log.d(TAG, "Thread id of sending message is " + getCurrentThreadId());
 5                 subscriber.onNext("hello");
 6             }
 7         }).subscribe(new Action1<String>() {
 8             @Override
 9             public void call(String s) {
10                 Log.d(TAG, "Thread id of receiving message is " + getCurrentThreadId());
11             }
12         });

这段代码很简单,分别在发送和接收的地方打印当前的线程id,log如下:

那么该如何切换线程呢?这里要用到两个方法:

  • subscribeOn:指定事件发生的线程
  • observeOn: 指定事件接收的线程

这两个方法都需要传入Scheduler对象,而这个对象可以通过Schedulers和AndroidSchedulers来获取。

  • Scheduler.newThread():始终开启新的线程
  • Scheduler.immediate():当前线程(默认)
  • Scheduler.io():IO线程,如网络下载,文件读写
  • Scheduler.computation():计算线程,如图形计算等
  • AndroidSchedulers.mainThread():Android中的UI线程
  • AndroidSchedulers.from(Looper looper):根据Looper来获取对应的线程,这里可以根据Handler来取得Handler对应的线程

如果我们需要在新的线程中进行消息发送(网络下载),在UI线程中更新UI,那么代码应该如下所示:

 1         O
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇实用控件分享:自定义逼真相机光.. 下一篇Android版本控制系统及其间的差异

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目