2024年安卓最全RxJava零基础入门(三)(1),2024年最新Android系列学习进阶视频

最后

针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

  • Android前沿技术大纲

  • 全套体系化高级架构视频

Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

所以用Map是无法实现直接打印学校的所有学生名字的,因为Map是一对一的关系,无法将单一的School对象转变成多个Student。前面说到,FlatMap可以改变原始Observable变成另外一个Observable,如果我们能利用from()操作符把school.getStudentList()变成另外一个Observable问题不就迎刃而解了吗,这时候就该FlatMap上场了,来看看它是怎么实现的:


Observable.from(schoolList).flatMap(new Func1<School, Observable<School.Student>>() {

  @Override

  public Observable<School.Student> call(School school) {



      return Observable.from(school.getStudentList()); //关键,将学生列表以另外一个Observable发射出去



  }}).subscribe(new Action1<School.Student>() {



  @Override

  public void call(School.Student student) {

      Log.i("mytag",student.getName());

  }});

值得注意的是,flatMap并不保证变换后事件的发送顺序,如果要保证其顺序,建议使用concatMap操作符

Map和FlatMap在我看来就像孪生兄弟一样,非常实用,实际开发中也我也经常使用,个人觉得要想上手RxJava,掌握这两个操作符必不可少。

Map 与 flatMap 这两个操作符的共同点在于,他们都是把一个对象转换为另一个对象,但须注意以下这些特点:

1.flatMap 返回的是一个Observable对象,而 map 返回的是一个普通转换后的对象;

2.flatMap 返回的Observable对象并不是直接发送到Subscriber的回调中,而是重新创建一个Observable对象,并激活这个Observable对象,使之开始发送事件;而 map 变换后返回的对象直接发到Subscriber回调中;

3.flatMap 变换后产生的每一个Observable对象发送的事件,最后都汇入同一个Observable,进而发送给Subscriber回调;

4.map返回类型 与 flatMap 返回的Observable事件类型,可以与原来的事件类型一样;

5.可以对一个Observable多次使用 map 和 flatMap;

  • Buffer: 缓存,可以设置缓存大小,缓存满后,以list的方式将数据发送出去;例:

Observable.just(1,2,3).buffer(2).subscribe(new Action1<List<Integer>>() {

  @Override

  public void call(List<Integer> list) {

      Log.i("mytag","size:"+list.size());

  }});

运行打印结果如下:


11-02 20:49:58.370 23392-23392/? I/mytag: size:2

11-02 20:49:58.370 23392-23392/? I/mytag: size:1

在开发当中,个人经常将Buffer和Map一起使用,常发生在从后台取完数据,对一个List中的数据进行预处理后,再用Buffer缓存后一起发送,保证最后数据接收还是一个List,如下:


List<School> schoolList = new ArrayList<>();

Observable.from(schoolList).map(new Func1<School, School>() {

  @Override

  public School call(School school) {

      school.setName("NB大学");  //将所有学校改名

      return school;

  }}).buffer(schoolList.size())  //缓存起来,最后一起发送

.subscribe(new Action1<List<School>>() {

  @Override

  public void call(List<School> schools) {   

}});

  • **Take:**发射前n项数据,还是用上面的例子,假设不要改所有学校的名称了,就改前四个学校的名称:

Observable.from(schoolList).take(4).map(new Func1<School, School>() {

  @Override

  public School call(School school) {

      school.setName("NB大学");

      return school;

  }}).buffer(4).subscribe(new Action1<List<School>>() {

  @Override

  public void call(List<School> schools) {

  }});

  • Distinct: 去掉重复的项,比较好理解:

Observable.just(1, 2, 1, 1, 2, 3)

      .distinct()

      .subscribe(new Action1<Integer>() {

          @Override

          public void call(Integer item) {

              System.out.println("Next: " + item);

          }

      });

输出


Next: 1

Next: 2

Next: 3

  • **Filter:**过滤,通过谓词判断的项才会被发射,例如,发射小于4的数据:

Observable.just(1, 2, 3, 4, 5)

      .filter(new Func1<Integer, Boolean>() {

          @Override

          public Boolean call(Integer item) {

              return( item < 4 );

          }

      }).subscribe(new Action1<Integer>() {

        @Override

        public void call(Integer item) {

              System.out.println("Next: " + item);

    }});

输出:


Next: 1

Next: 2

Next: 3

以下内容摘自http://blog.csdn.net/u012124438/article/details/53730717

  • zip

Zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。


Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {

        @Override

        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {

            Log.d(TAG, "emitter 1");

            emitter.onNext(1);

            Log.d(TAG, "emitter 2");

            emitter.onNext(2);

            Log.d(TAG, "emitter 3");

            emitter.onNext(3);

            Log.d(TAG, "emitter 4");

            emitter.onNext(4);

            Log.d(TAG, "emit complete1");

            emitter.onComplete();

        }

    });



    Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {

        @Override

        public void subscribe(ObservableEmitter<String> emitter) throws Exception {

            Log.d(TAG, "emitter A");

            emitter.onNext("A");

            Log.d(TAG, "emitter B");

            emitter.onNext("B");

            Log.d(TAG, "emitter C");

            emitter.onNext("C");

            Log.d(TAG, "emitter complete2");

            emitter.onComplete();

        }

    });



    Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {

        @Override

        public String apply(Integer integer, String s) throws Exception {

            return integer + s;

        }

    }).subscribe(new Observer<String>() {

        @Override

        public void onSubscribe(Disposable d) {

            Log.d(TAG, "onSubscribe");

        }



        @Override

        public void onNext(String value) {

            Log.d(TAG, "onNext: " + value);

        }



        @Override

        public void onError(Throwable e) {

            Log.d(TAG, "onError");

        }



        @Override

        public void onComplete() {

            Log.d(TAG, "onComplete");

        }

    });

我们分别创建了observable, 一个发送1,2,3,4,Complete, 另一个发送A,B,C,Complete, 接着用Zip把发出的事件组合, 来看看运行结果吧:

这里写图片描述

观察发现observable1发送事件后,observable2才发送

这是因为我们两个observable都是运行在同一个线程里, 同一个线程里执行代码肯定有先后顺序呀.


Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {

        @Override

        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {

            Log.d(TAG, "emit 1");

            emitter.onNext(1);

            Thread.sleep(1000);



            Log.d(TAG, "emit 2");

            emitter.onNext(2);

            Thread.sleep(1000);



            Log.d(TAG, "emit 3");

            emitter.onNext(3);

            Thread.sleep(1000);



            Log.d(TAG, "emit 4");

            emitter.onNext(4);

            Thread.sleep(1000);



            Log.d(TAG, "emit complete1");

            emitter.onComplete();

        }

    }).subscribeOn(Schedulers.io());



    Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {

        @Override

        public void subscribe(ObservableEmitter<String> emitter) throws Exception {

            Log.d(TAG, "emit A");

            emitter.onNext("A");

            Thread.sleep(1000);



            Log.d(TAG, "emit B");

            emitter.onNext("B");

            Thread.sleep(1000);



            Log.d(TAG, "emit C");

            emitter.onNext("C");

            Thread.sleep(1000);



            Log.d(TAG, "emit complete2");

            emitter.onComplete();

        }

    }).subscribeOn(Schedulers.io());



    Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {

        @Override

        public String apply(Integer integer, String s) throws Exception {

            return integer + s;

        }

    }).subscribe(new Observer<String>() {

        @Override

        public void onSubscribe(Disposable d) {

            Log.d(TAG, "onSubscribe");

        }



        @Override

        public void onNext(String value) {

            Log.d(TAG, "onNext: " + value);

        }



        @Override

        public void onError(Throwable e) {

            Log.d(TAG, "onError");

        }



        @Override

        public void onComplete() {

            Log.d(TAG, "onComplete");

        }

    });

好了, 这次我们让事件都在IO线程里发送事件, 再来看看运行结果:

这里写图片描述

:zip的代码是基于Rxjava2的

第一个observable明明发送了四个数据+一个Complete, 之前明明还有的, 为啥到这里没了呢?

这是因为我们之前说了, zip发送的事件数量跟observable中发送事件最少的那一个的事件数量是有关的, 在这个例子里我们observable2只发送了三个事件然后就发送了Complete, 这个时候尽管observable1还有事件4 和事件Complete 没有发送, 但是它们发不发送还有什么意义呢?

  • compose

与 flatMap 类似,都是进行变换,返回Observable对象,激活并发送事件。

1.compose 是唯一一个能够从数据流中得到原始Observable的操作符,所以,那些需要对整个数据流产生作用的操作(比如,subscribeOn()和observeOn())需要使用 compose 来实现。相较而言,如果在flatMap()中使用subscribeOn()或者observeOn(),那么它仅仅对在flatMap 中创建的Observable起作用,而不会对剩下的流产生影响。这样就可以简化subscribeOn()以及observeOn()的调用次数了。

2.compose 是对 Observable 整体的变换,换句话说, flatMap 转换Observable里的每一个事件,而 compose 转换的是整个Observable数据流。

3.flatMap 每发送一个事件都创建一个 Observable,所以效率较低。而 compose 操作符只在主干数据流上执行操作。

4.建议使用 compose 代替 flatMap。

  • merge

merge操作符可以合并多个Observable的输出,如果多个Observable运行在同一个线程,不会出现交错发射,如果都subscribeOn(Schedules.io())线程上,那就有可能会出现交错发射,具体原因点此查看。而可利用concat操作符可以保持顺序。

这里写图片描述

如果某个原始Observable出现onError,merge后的Observable就会onError,onNext就都不会调用执行了。

结语

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是目录截图:

由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。

再附一部分Android架构面试视频讲解:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

ps://img-blog.csdn.net/20160912185524453)

如果某个原始Observable出现onError,merge后的Observable就会onError,onNext就都不会调用执行了。

结语

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是目录截图:

[外链图片转存中…(img-Kz7NgKbG-1715749987195)]

由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。

再附一部分Android架构面试视频讲解:

[外链图片转存中…(img-G46pSZFw-1715749987195)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值