前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Architecting Android with RxJava

Architecting Android with RxJava

作者头像
小鄧子
发布于 2018-08-20 07:11:55
发布于 2018-08-20 07:11:55
52100
代码可运行
举报
运行总次数:0
代码可运行

最近,我抽出了几个晚上的时间,把咖啡和啤酒变成了代码与文字。

引子

三个月以来,我翻译了一些关于RxJava的文章,说实话这些翻译,真的搞得我很头疼,那么现在是时候回来写点什么了。

最近,我在看两本书,《Learning Reactive Programming with Java 8》《RxJava Essentials》,不过,没关系,我已经买到了电子版,我会在文章结尾附上网盘链接和密码,但我还是希望你将文章继续读下去,因为那是文章结尾的事。

其实关于RxJava的文章和消息远不止我们能了解到的,但又拜英语所赐,所以它看起来又没那么多。好在,国内有许多优秀的开发专家hi大头鬼hi

BlackSwift程序亦非猿Drakeet扔物线流火枫林等等在为之做着贡献,以及简直不能更优秀的文章《给 Android 开发者的 RxJava 详解》

但是,现在,我不得不再次做啰嗦一下,RxJava究竟会改变我们什么。

响应式编程Reactive Programming

什么是响应式编程呢?在Java程序中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a = 4;
int b = 5;
int c = a + b;
System.out.println(c); // 9
a = 6;
System.out.println(c);
// 9 again, but if 'c' was tracking the changes of 'a' and 'b',
// it would've been 6 + 5 = 11

当我们改变“a”和“b”的值时,“c”并没有改变。换句话说,“a”和“b”的改变并没有响应到“c”。这就是响应式:程序以流的形式,传递数据的改变

那我,我们又为什么需要响应式呢?

以下翻译自《Learning Reactive Programming with Java 8》

10-15年前,对于网站开发来说,最平常的日常工作就是进行维护和缩短响应时间,那么今天,一切程序都应该保证七天二十四小时不间断运行,并且能够极快的做出响应;如果你的网站响应慢或者宕机,那么用户将会对你们真爱一秒变备胎,转而选择其他网站服务。当今的慢意味着不可用甚至是有故障的。如今的互联网是在和大数据打交道,所以我们需要快速的处理数据。 过去的几年中HTTP错误已经不是什么新鲜事了,但是现在,我们不得不进行容错机制,还要提供用户易读以及合理的消息更新。 在过去,我们写简单的桌面应用,但如今我们写能够做出快速响应的Web应用。多数情况下,这些应用要与大量的远程服务器进行数据传递。 如果我们想让自己的软件保持竞争性,就不得不实现这些新需求,所以,换言之就是我们应该这样做:

  • 模块的/动态的:用这种方式,我们就能够拥有一个七天二十四小时的系统了,因为这些模块能够在不停止整个系统的情况下进行脱机和联机。另外,随着系统的不断庞大,还能帮助我们更好地组织应用结构,同时还能管理底层代码。
  • 可扩展的:用这种方式,我们就能够处理大量的数据和用户请求了。
  • 容错性:用这种方式,能够为用户提供稳定的系统。
  • 响应式:这不仅意味着快速,还意味着可用性强。

让我们思考如何实现它:

  • 如果我们的系统是事件驱动型的,那就把它模块化。我们可以将系统分成多个彼此之间通过通知进行交互的微服务/组件/模块。这样,我们就能够以通知为代表,响应系统的数据流了。
  • 可扩展意味着能够应对日益增长的数据,在负载的情况下不会崩溃。
  • 对故障/错误做出及时的响应,能够提高系统的容错性。
  • 响应意味着对能够对用户操作及时的做出反应。

如果应用是事件驱动型的,那么,它就能够解耦成多个自包含组件。这能够帮我们更好的实现扩展性,因为我们总是可以在不停掉或者打断系统的情况下添加新组建或者移除旧组件。如果错误和故障传递给正确的组件,把它们当做通知来处理并作出响应,那么应用能变得更具有容错性和弹性。所以,如果把系统构建成事件驱动型的。我们可以更容易的实现扩展性和容错性,而且一个具有扩展性,低耦合和防错的应用能够快速的响应用户操作。

Reactive Manifesto文档定义了我们刚刚提到的四点响应式准则。每一个响应式系统都应该是消息驱动型(事件驱动型)的。这样它不仅能变得低耦合,而且扩展性和容错性将更高,这就意味着它可靠和具有响应式。 要注意的是,Reactive Manifesto只是描述了一个响应式系统,并不是对响应式编程的定义。当然,你也可以不使用任何响应式类库或者语言,打造一款弹性可扩展,具有消息驱动的响应式应用。 应用程序中数据的变化,以通知的方式传递给正确的Handler。所以,使用响应式构造应用是符遵循Manifesto最简单的方式。

回调地狱

如果你是一个能够时刻保持头脑清醒,逻辑清晰和思维缜密的人,是个Callback高手,善用并且能够用好FutureTask

那么在Android中你的代码可能会频繁的使用async+callbacks,或者service composition+ error handing

那么关于异步回调的逻辑,你会写成这样getData(Callback<T>)、这样Future<T> getData(),还是这样Future<List<T>> getData(),甚至这样Future<List<Future<T>>> getData(),嗷!拜托,我简直不能再举例下去了,这简直就是Callback Hell,这样的程序或许写起来很舒服,但是如何测试和维护呢。

如果哪天你的程序出了问题而必须马上修复,但你却不能马上赶来或者需要别人协助(这在很多公司是很常见的),或者当他人在review你的代码时,那么,是时候拿出这张图了。

然而使用RxJava的操作符,我们可以避免这些烦人甚至糟糕的回调,让结构和思路看起来更清晰,通过组合API,只需要约定最终的结果Observable<T>就行了。

并且scheduler的出现,不仅解放了线程的切换,让UI线程与工作线程间的跳转变得简单,而且,它的API很丰,也提供了很多使用场景的建议,比如,适用计算任务的Schedulers.computation( );处理密集IO任务的Schedulers.io( );以及Schedulers.trampoline( )能够有效避免StackOverflowError,所以非常适合函数的递归调用。好了,我不再举例了,因为官方文档已经给出了很详细的解释了,但是值得一提的是,如果使用Schedulers的工厂方法创建的Worker,一旦任务执行完毕,都应该调用worker.unsubscribe( )方法,然后转向之前定义的Scheduler实例上来。

当然RxJava的出现并不仅仅是为了解决回调地狱的。

这是我通过学习和不断地练习,一路走来很辛苦,总结的一些经验,分享给大家:

1 . error handling

2 . lifecycle changes

3 . caching (roation)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   @Override public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setRetainInstance(true);

      /*.cache()操作符:
        当第一个subscribe订阅的时候,才会连接原始Observable,缓存事件,重发给后续订阅的subscribe
        值得注意的事,它和使用了.replay()操作符的ConnectableObservable的不同。
        另外,为了避免内存开销,不建议缓存大量事件*/
      cacheObservable = weatherManager.getWeather().cache();
    }

    @Override public void onViewCreated(View view, Bundle savedInstanceState) {
      super.onViewCreated(view, savedInstanceState);
      cacheObservable.subscribe(/*your subscribe*/);
    }

4 . composing multiple calls

5 . more robust interface than asyncTask

6 . easy to do complex threading

7 . functional nature is more expressive

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /*一个数组,每个元素乘以2,然后筛选小于10的元素,放入集合中*/
    Integer[] integers = { 0, 1, 2, 3, 4, 5 };

    /*一般写法,看上去并不是那么的“函数”*/
    Integer[] doubles = new Integer[integers.length];
    for (int i = 0; i < integers.length; i++) {
      doubles[i] = integers[i] * 2;
    }
    List<Integer> integerList = new ArrayList<>(doubles.length);
    for (Integer integer : doubles) {
      if (integer < 10) integerList.add(integer);
    }


    /*Observable写法,一切都好多了*/
    List<Integer> funactionalList = Observable.from(integers).map(new Func1<Integer, Integer>() {
      @Override public Integer call(Integer integer) {
        return integer * 2;
      }
    }).filter(new Func1<Integer, Boolean>() {
      @Override public Boolean call(Integer integer) {
        return integer < 10;
      }
    }).toList().toBlocking().first();

8 . async unit testing

9 . fluent API

10 . easy debugging

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//值得一提的是,关于@RxLogSubscriber要放在继承自Subscriber的类上
@RxLogSubscriber class MySubscriber extends Subscriber<Void> {
        @Override public void onCompleted() {
        }
        @Override public void onError(Throwable e) {
        }

        @Override public void onNext(Void aVoid) {
        }
      }

//而不是实现Observer接口的类上
@RxLogSubscriber class MySubscriber implements Observer<Void> {
        @Override public void onCompleted() {
        }
        @Override public void onError(Throwable e) {
        }

        @Override public void onNext(Void aVoid) {
        }
      }

当然,随着学习的深入,你会发现,收益不止如此。

在响应式编程中,应该牢记以下两点:

  • everything is a stream(一切皆流)
  • don't break the chain(不要打断链式结构)

谈谈Backpressure

Android这种嵌入式系统,尤其是生产者-消费者(producer-consumer)模式中,一定要小心Backpressure(背压,反压)的出现。一个宽泛的解释就是:事件产生的速度比消费快。一旦发生overproducing,当你的链式结构不能承受数据压力的时候,就会抛出MissingBackpressureException异常。

在Android中最容易出现的Backpressure就是连续快速点击跳转界面、数据库查询、文件扫面、键盘输入,甚至联网等操作都有可能造成Backpressure,可能有些情况并不会导致程序崩溃,但是会造成一些我们不想见到的小麻烦。那么一起来看看如何用RxJava解决Backpressure,OK,让我们的程序变得健壮起来吧。

groupBy操作符

在写这篇文章的时候,刚好看到一段代码,看来有必要说一说这个操作符了。

.groupBy( ),分组操作符,虽然目前这个项目中没有用到,但是我还是蛮喜欢它的,而且我看到很多人在使用,将原始Observable根据不同的key分组成多个GroupedObservable,由原始Observable发射(原始Observable的泛型将变成这样Observable<GroupedObservable<K, T>>),每一个GroupedObservable既是事件本身也是一个独立的Observable,每一个GroupedObservable发射一组原始Observable的事件子集。

引用自:GroupBy中文翻译

注意:groupBy将原始Observable分解为一个发射多个GroupedObservable的Observable,一旦有订阅,每个GroupedObservable就开始缓存数据。因此,如果你忽略这些GroupedObservable中的任何一个,这个缓存可能形成一个潜在的内存泄露。因此,如果你不想观察,也不要忽略GroupedObservable。你应该使用像take(0)这样会丢弃自己的缓存的操作符。 如果你取消订阅一个GroupedObservable,那个Observable将会终止。如果之后原始的Observable又发射了一个与这个Observable的Key匹配的数据,groupBy将会为这个Key创建一个新的GroupedObservable。

那么问题恰恰出在.take(n)操作符上。

只返回前面指定的n项数据,然后发送完成通知,忽略后面的事件。

那么看一下这个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Observable.just(0, 1, 2, 3, 4, 5).groupBy(new Func1<Integer, Boolean>() {
          @Override public Boolean call(Integer integer) {
            return integer % 2 == 0;
          }
        }).flatMap(new Func1<GroupedObservable<Boolean, Integer>, Observable<Integer>>() {
          @Override
          public Observable<Integer> call(GroupedObservable<Boolean, Integer> groupedObservable) {

            return groupedObservable.getKey() ? groupedObservable.take(1) : groupedObservable;
          }
        }).subscribe(new Action1<Integer>() {
          @Override public void call(Integer i) {
            System.out.println(i);
          }
        });

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
0
1
2
3
4
5

然而在1.0.0-RC5之前的版本中,在GroupedObservable上使用.take(n)操作符将会在发送完n个事件后,对GroupedObservable进行unsubscribe。并且GroupedObservable内部将会记录这个unsubscribed状态,然后忽略后面的事件。所以输出结果将是这样的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
0
1
3
5

而在这之后的版本,使用.take(n)操作符,虽然也会发生unsubscribe,但是当原始Observable再次发送一个满足key的事件后,将会重新创建一个GroupedObservable,然后发送这个GroupedObservable,不会发生之前那样的,忽略后续事件的现象。

当然,不要忘记,对不感兴趣的GroupedObservable使用.take(0),来避免泄露。

所以,我的建议是,在使用RxJava之前看看官方文档或者change log。

关于RxWeather

我尽量减少对这个工程的文字描述。因为代码才是最好的老师。

通过对Android技术栈,1#架构译文)和Android架构演化之路译文)的解读和学习,按照架构和思路进行了实现,并且加入了RxBus。

关于REST API,我选择了和风天气,而放弃了Openweathermap的理由如下:

  1. Openweathermap免费用户所在的服务器不稳定。
  2. 付费方面,和风天气更经济实惠。

但是和风天气目前并不支持同时查询多个地区的天气预报,也不支持根据经纬度查询天气预报。但是以后的事情谁又能说的准呢?

由于应用并不支持动态的上拉加载。所以,所有的列表展示结果,取决于city.txt文件。

我从Openweathermap给出的资源(下载city.list.json)中,整理需要的城市Json字符串,整合了经纬度,以备不时之需。

找到了一个通过Location查询所在地的API。

就这样基本实现了列表展示页ListActivity的功能:

  1. 根据Loaction查询所在地城市名称,然后查询当地天气。
  2. 读取domain->assets->city.txt,然后依次查询每个城市的天气,所以,这个文件不建议放入太多json。
  3. 整合1和2的并发请求结果,显示界面。

详情页DetailActivity通过RxBus发送黏性事件接收列表页传递过来的数据,然后进行展示。这里会有七天内的天气以及穿衣建议。由于我么并没有找到一个正确的算法,所以当进入详情页后,旋转屏幕之后的退出动画会有所不同。这个类涉及的代码大部分都是动画(注意Hardware Layer的使用)以及对屏幕旋转的处理,所以代码看起有点多。ForkView使用了一个简单的自定义Behavior

搜索界面SearchActivity,输入的关键字请不要以市、区结尾,例如,北京而不是北京市,因为API不支持,我也没办法 :( 。

启动页

我认为,出彩的引导页是对细节的重视,但是我实在不能忍受,在启动页等太久。注意:不要混淆这两种场景。

所以,我在看了正确使用启动页之后,决定采取这种方式实现SplashActivity。而且不建议使用大图,一个icon足以。

Code

所有代码都可以从Github上获得。

片尾Tips:

文章开头提到的资料,需要pdf或者kindle版本的请自行选择下载,不得用于商业用途。

Learning Reactive Programming with Java 8 - pdf版,提取密码:2d88。

Learning Reactive Programming with Java 8 - kindle版,提取密码:5nec。

RxJava Essentials - pdf版,提取密码:z3r8。

RxJava Essentials - kindle版,提取密码:l67e。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015.11.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Rxjava2最全面的解析
前言 由于公司重新规划的部门,我调到了另外一个部门,所以负责的项目也换了,仔细看了下整体的项目,rxjava+retrofit。整体的一套。众所周知,rxjava+retrofit是目前网上最流行的网络解析框架。而目前网络上的文章大多还是关于rxjava1的。关于RxJava2的少之又少,于是,便有了此文。 此文的目的有三个: 1. 给对 RxJava2感兴趣的人一些入门的指引 2. 给正在使用 RxJava2但仍然心存疑惑的人一些更深入的解析 3.给想从RxJava1替换成RxJava2的人给出直接的对
我就是马云飞
2018/02/05
2.5K0
Rxjava2最全面的解析
RxJava for Android学习笔记
Android工程引入RxJava-android 请引入Rxandroid库: compile 'io.reactivex:rxandroid:1.2.1' 一简介 1.1 Rx结构 响应式编程的主要组成部分是observable, operator和susbscriber,一般响应式编程的信息流如下所示: Observable -> Operator 1 -> Operator 2 -> Operator 3 -> Subscriber 也就是说,observable是事件的生产者,subscriber是事件最终的消费者。 因为subscriber通常在主线程中执行,因此设计上要求其代码尽可能简单,只对事件进行响应,而修改事件的工作全部由operator执行。 在响应式编程中,应该牢记以下两点:everything is a stream(一切皆流)don't break the chain(不要打断链式结构) 1.2 最简单的模式 如果我们不需要修改事件,就不需要在observable和subscriber中插入operator。这时的Rx结构如下: Obsevable -> Subscriber 这看起来很像设计模式中的观察者模式,他们最重要的区别之一在于在没有subscriber之前,observable不会产生事件。
Anymarvel
2018/10/22
7610
RxJava for Android学习笔记
Android RxJava的使用
首语 最近因为项目上线,挤不出时间,已经好久没有更新博客了😛,目前项目也做差不多了,写几篇总结类型的博客,梳理一下。 本文主要对RxJava及常用操作符的使用进行总结,同时对RxJava在Android中几种常见的使用场景进行举例。 简介 RxJava是Reactive Extensions的Java VM实现:该库用于通过使用可观察的序列来组成异步和基于事件的程序。 Rx是Reactive Extensions的缩写的简写,它是一个使用可观察数据流进行异步编程的编程接口,Rx结合了观察者模式、迭代器模
八归少年
2022/06/29
3.1K0
Android RxJava的使用
Android :RxJava2.0到底更新了什么?(含使用建议)
在`RxJava 2.0 `中,创建被观察者(`Observable`) & 观察者(Observer)的方式也与`RxJava 1.0 `有些区别:
Carson.Ho
2019/02/22
1.1K0
【译】RxJava变换操作符:-concatMap(-)与-flatMap(-)的比较
是时候回归写作了。(译者注:原作者吧啦吧啦唠家常,这里就不做翻译了,但是,有两个重要的链接,点我,再点我)
用户1740424
2018/07/23
8400
【译】RxJava变换操作符:-concatMap(-)与-flatMap(-)的比较
RxJava系列一(简介)
前言 提升开发效率,降低维护成本一直是开发团队永恒不变的宗旨。近一年来国内的技术圈子中越来越多的开始提及Rx,经过一段时间的学习和探索之后我也深深的感受到了RxJava的魅力。它能帮助我们简化代码逻辑,提升代码可读性。这对于开发效率的提升、后期维护成本的降低帮助都是巨大的。个人预测RxJava一定是2016年的一个大趋势,所以也有打算将它引入到公司现有的项目中来,写这一系列的文章主要也是为了团队内部做技术分享。 由于我本人是个Android程序猿,因此这一系列文章中的场景都是基于Android平台的。
张磊BARON
2018/04/13
7380
RxJava系列一(简介)
RxJava2
函数式编程是一种编程范式。我们常见的编程范式有命令式编程、函数式编程和逻辑式编程。我们常见的面向对象编程是一种命令式编程。命令式编程是面向计算机硬件的抽象,有变量、赋值语句、表达式和控制语句。而函数式编程是面向数学的抽象,将计算描述为一种表达式求值,函数可以在任何地方定义,并且可以对函数进行组合。响应式编程是一种面向数据流和变化传播的编程范式,数据更新是相关联的。把函数式编程里的一套思路和响应式编程合起来就是函数响应式编程。函数响应式编程可以极大地简化项目,特别是处理嵌套回调的异步事件、复杂的列表过滤和变换或者时间相关问题。在Android开发中使用函数响应式编程的主要有两大框架: 一个是 RxJava,另一个是 Goodle 推出的 Agera。本章我们来学习 RxJava。
acc8226
2022/05/17
7640
RxJava2
RxJava系列三(转换操作符)
前面两篇文章中我们介绍了RxJava的一些基本概念和RxJava最简单的用法。从这一章开始,我们开始聊聊RxJava中的操作符Operators,后面我将用三章的篇幅来分别介绍: 转换类操作符 过滤类
张磊BARON
2018/04/13
7200
RxJava系列三(转换操作符)
RxJava从入门到不离不弃(一)——基本概念和使用
RxJava的编程思想已经在Android开发者中变得越来越流行。有个不好的点就是上手不太容易,尤其是大部分人之前都是使用命令式编程语言。
蜻蜓队长
2018/08/03
8320
RxJava从入门到不离不弃(一)——基本概念和使用
[译]初识RxJava 2 for Android
本文介绍了RxJava的基本组件,包括创建Observer和Observable的方法,以及使用更少的代码创建不同Observable的操作符。此外,还介绍了如何根据文章内容撰写文章的摘要总结。
MelonTeam
2018/01/04
1.2K0
[译]初识RxJava 2 for Android
[享学Netflix] 十六、Hystrix断路器:初体验及RxJava简介
代码下载地址:https://github.com/f641385712/netflix-learning
YourBatman
2020/03/18
2.4K0
RxJava 1.x 笔记:变换型操作符
张拭心 shixinzhang
2018/01/05
9970
RxJava 1.x 笔记:变换型操作符
RxJava 并行操作
上一篇文章RxJava 线程模型分析详细介绍了RxJava的线程模型,被观察者(Observable、Flowable...)发射的数据流可以经历各种线程切换,但是数据流的各个元素之间不会产生并行执行的效果。我们知道并行并不是并发,不是同步,更不是异步。
fengzhizi715
2018/08/24
1.5K0
RxJava 并行操作
Rx Java 异步编程框架
在很多软件编程任务中,或多或少你都会期望你写的代码能按照编写的顺序,一次一个的顺序执行和完成。但是在ReactiveX中,很多指令可能是并行执行的,之后他们的执行结果才会被观察者捕获,顺序是不确定的。为达到这个目的,你定义一种获取和变换数据的机制,而不是调用一个方法。在这种机制下,存在一个可观察对象(Observable),观察者(Observer)订阅(Subscribe)它,当数据就绪时,之前定义的机制就会分发数据给一直处于等待状态的观察者哨兵。
架构探险之道
2023/03/04
3.3K0
Rx Java 异步编程框架
关于RxJava2.0你不知道的事(一)
2017年的首篇文章,本次依旧带来一叶飘舟的开年之作,新的一年祝大家事业有成,爱情美满!
开发者技术前线
2020/11/23
1.5K0
关于RxJava2.0你不知道的事(一)
RxJava的一些入门学习分享
最近在Android编程领域,RxJava这个框架的技术热度相当的高。团队对使用RxJava改进目前的项目代码也表示很有兴趣,所以我特地和团队伙伴一起对这套框架做了一下调研。现在就把目前对RxJava的一些理解和粗浅的分析做一下分享,欢迎大家拍砖。 1.什么是RxJava 要了解什么是RxJava,先需要了解一下它的理念来源:ReactiveX。 ReactiveX是Reactive Extensions的缩写,一般简写为Rx,最初是LINQ的一个扩展,由微软的架构师Erik Meijer领导的团队开发
QQ音乐技术团队
2018/01/30
1.3K0
RxJava的一些入门学习分享
RxJava1.X升级到RxJava2.X笔记
RxJava 2.X不再支持null值,如果传入一个null会抛出NullPointerException
续写经典
2018/08/28
9160
RxJava1.X升级到RxJava2.X笔记
八个层面比较 Java 8, RxJava, Reactor
这是一篇译文,原文出处(http://alexsderkach.io/comparing-java-8-rxjava-reactor/)。其实很久以前我就看完了这篇文章,只不过个人对响应式编程研究的不够深入,羞于下笔翻译,在加上这类译文加了原创还有争议性,所以一直没有动力。恰逢今天交流群里两个大佬对响应式编程的话题辩得不可开交,趁印象还算深刻,借机把这篇文章翻译一下。说道辩论的点,不妨也在这里抛出来:
kirito-moe
2018/10/22
3.6K0
八个层面比较 Java 8, RxJava, Reactor
RxJava简析
rxjava文档地址https://mcxiaoke.gitbooks.io/rxdocs/content/ 这个是中文版的
用户3112896
2020/11/25
7490
一篇RxJava友好的文章(一)
本文介绍了如何使用 RxJava 操作符简化 Android 代码,包括 map、filter、flatMap、take 等操作符的使用。简化复杂的逻辑,让代码更加简洁易读,提高开发效率。
方志朋
2017/12/29
9090
一篇RxJava友好的文章(一)
相关推荐
Rxjava2最全面的解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验