【问题标题】:RxJava instead of AsyncTask?RxJava 而不是 AsyncTask?
【发布时间】:2017-01-05 22:43:00
【问题描述】:

当人们试图说服我使用 RxJava 而不是 Android 的标准 AsyncTask 构造时,我遇到了几个例子。

在我看来,RxJava 提供了更多的功能,但与AsyncTask 相比在简单性上有所逊色。

是否有任何用例比另一种更适合一种方法,甚至更通用,RxJava 甚至可以被认为是优越的?

【问题讨论】:

  • 我看到这篇文章解释了原因,如果有帮助的话。 blog.feedpresso.com/2016/01/25/…
  • 谢谢。它看起来有点像 Scala 处理并发的方式。我将在我的项目中进行一些测试以适应 RxJava。但是,您认为 AsyncTask 的功能存在根本缺陷吗?

标签: java android concurrency android-asynctask rx-java


【解决方案1】:

当您在 Java 8 上使用 RxJava 时,可以看到 RxJava 的全部功能,最好使用 Retrofit 之类的库。它允许您将操作简单地链接在一起,并完全控制错误处理。例如,考虑以下代码给定的id:一个指定订单的 int 和 apiClient:订单管理微服务的改造客户端:

apiClient
.getOrder(id)
.subscribeOn(Schedulers.io())
.flatMapIterable(Order::getLineItems)
.flatMap(lineItem ->
    apiClient.getProduct(lineItem.getProductId())
             .subscribeOn(Schedulers.io())
             .map(product -> product.getCurrentPrice() * lineItem.getCount()),
    5)
.reduce((a,b)->a+b)
.retryWhen((e, count) -> count<2 && (e instanceof RetrofitError))
.onErrorReturn(e -> -1)
.subscribe(System.out::println);

这将异步计算订单的总价格,具有以下属性:

  • 任何时候最多 5 个针对运行中的 API 的请求(您可以调整 IO 调度程序以对所有请求设置硬上限,而不仅仅是单个可观察链)
  • 在出现网络错误时最多重试 2 次​​li>
  • -1 在失败的情况下(反模式 TBH,但这是另一个讨论)

此外,IMO 每次网络调用后的 .subscribeOn(Schedulers.io()) 应该是隐式的 - 您可以通过修改创建 Retrofit 客户端的方式来做到这一点。对于 11+2 行代码来说还不错,即使它比 Android 更像后端。

【讨论】:

  • 非常感谢您提供这个详细的示例。我期待着修补那些一流的功能。很久没有在 Java 中这样做了。
  • 我宁愿拥有 5 倍的代码行数,并且更容易理解和维护。 Rx 有它的用处,但链式使得只写这样的代码变得难以理解。
【解决方案2】:

Jake Wharton 的 RxBinding/RxAndroid 提供了一些不错的线程功能,可用于进行异步调用,但 RxJava 提供的好处/功能远不止处理异步线程。也就是说,学习曲线非常陡峭(IMO)。另外,需要注意的是,使用 AsyncTasks 并没有什么问题,你可以用 Rx(也就是 IMO)编写更雄辩的解决方案。

TLDR 你应该努力使用它。 Retrofit 和 RxJava 可以很好地配合使用,以实现 AsyncTask 替换目的。

【讨论】:

  • 酷。那么你会说 AsyncTask 适合像简单的 HTTP 处理程序这样的小型项目吗?
  • 当然可以,但是您可以使用 RxJava/RxBinding/RxAndroid 完成相同的事情,并且这样做可能会获得一些很酷的点。
  • 非常好。我一直在寻找优雅。 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
相关资源
最近更新 更多