数据结构链表例程
by Ayusch Jain
通过Ayusch Jain
如何掌握RxJava例程的四个结构 (How to get a grip on the four constructs of an RxJava routine)
RxJava has become the single most important weapon in the android development arsenal. Every developer in 2019 must start using it in their apps if they haven’t already. According to the official definition of RxJava:
RxJava已成为android开发工具库中最重要的武器。 如果还没有,2019年的每个开发人员都必须开始在其应用程序中使用它。 根据RxJava的官方定义:
“RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.”
“ RxJava是Reactive Extensions的Java VM实现:一个库,用于通过使用可观察的序列来组成异步和基于事件的程序。”
This definition can sound intimidating with all the technical terms such as Java VM, Reactive Extensions, Asynchronous event-based, observable sequences etc. But guess what? You’ve been using all these things in your day to day android development tasks unknowingly.
这个定义听起来像所有技术术语一样令人生畏,例如Java VM,Reactive Extensions,基于异步事件,可观察的序列等。但是您猜怎么着? 您在不知不觉中一直在日常android开发任务中使用所有这些东西。
Note: I’m assuming that if you’re looking to dive deep into RxJava then you have a good knowledge of Java programming language. If not, you can find various online schools which can help you with this.
注意:我假设如果您想深入研究RxJava,那么您将对Java编程语言有很好的了解。 如果没有,您可以找到各种在线学校来帮助您。
入门 (Getting Started)
Let’s start with the Java VM (or JVM). Ever wondered how your code written using the English alphabet gets translated to pixels on the screen? How your color changes in code translate to color changes on the screen? Well, it’s all done by the JVM.
让我们从Java VM(或JVM)开始。 有没有想过使用英语字母编写的代码如何转换为屏幕上的像素? 您的代码颜色变化如何转换为屏幕上的颜色变化? 好吧,这一切都由JVM完成。
First, your source code is compiled into Bytecode by the compiler. Now comes in the JVM that takes that Bytecode and converts it into something that the machine can understand. In other languages, the compiler converts the code for a particular system, but Java’s compiler converts the source code to Bytecode which can be run on any machine with JVM.
首先,您的源代码被编译器编译为Bytecode。 现在出现在JVM中,该JVM使用该字节码并将其转换为机器可以理解的东西。 用其他语言 ,编译器将代码转换为特定系统,但是Java的编译器将源代码转换为Bytecode,可以在具有JVM的任何计算机上运行。
Now, do you understand why Kotlin can be used to write Android applications? If not, then be on the lookout for my next post.
现在,您了解为什么可以使用Kotlin编写Android应用程序吗? 如果没有,那么请注意我的下一篇文章。
React性扩展 (Reactive Extensions)
Reactive Extensions or ReactiveX has been around for a long time. It is nothing but an API that makes reactive programming easy.
Reactive Extensions或ReactiveX已经存在很长时间了。 它不过是使React式编程变得容易的API。
Unknowingly we have been writing reactive code all along. For example, when a button click happens, it triggers a certain block of code in your source file. This is reactive programming! A piece of code has reacted to an event (button click in this case).
不知不觉中我们一直在写React式代码。 例如,当单击按钮时,它将触发源文件中的特定代码块。 这是React式编程! 一段代码已对事件做出React(在这种情况下为单击按钮)。
Reactive Extensions is not specific to any programming language but more of a methodology which has been implemented in languages such as Java (RxJava), JavaScript (RxJS), C# (Rx.NET), Scala (RxScala) and many others! So, you see, ReactiveX is not language specific but is more of a design pattern that can be implemented in any language.
Reactive Extensions并非特定于任何编程语言,而是更多的一种已用Java(RxJava),JavaScript(RxJS),C#(Rx.NET),Scala(RxScala)等语言实现的方法! 因此,您看到,ReactiveX不是特定于语言的,而是更多的可以用任何语言实现的设计模式。
RxJava的构造 (Constructs of RxJava)
RxJava basically has 4 constructs:
RxJava基本上有4种构造:
- Observable 可观察的
- Scheduler 排程器
- Observer 观察者
- Subscriber 订户
These 4 components are present in all the RxJava routines. Although these are not necessary, I’d recommend that you stick to them as a beginner. Once you get comfortable with RxJava, you can throw the rules out the window and start playing around. But before you get to that level, just stick to the basics.
所有RxJava例程中都包含这4个组件。 尽管这些不是必需的,但我还是建议您初学者坚持使用它们。 一旦您对RxJava感到满意,就可以将规则扔出窗外,然后开始玩耍。 但是在达到那个水平之前,请坚持基础。
So let’s look at each one of these constructs in more detail.
因此,让我们更详细地研究这些构造中的每一个。
可观察的 (Observable)
An Observable is exactly what it sounds like: something that can be observed. An observable (button) in RxJava is watched upon by an Observer (code that runs on a button click) which reacts to any events emitted (button click event) by the observable. This pattern facilitates concurrent operations as the main thread need not be blocked while waiting for the observable to emit events. The observer is always ready to react as soon as the observable emits.
一个Observable正是它的听起来:可以观察到的东西。 RxJava中的可观察对象(按钮)由观察者(在按钮单击上运行的代码)监视,该观察者对可观察对象发出的任何事件(按钮单击事件)做出React。 这种模式有助于并发操作,因为在等待可观察对象发出事件时不需要阻塞主线程。 观察者总是准备好在观察到的物体发出后立即做出React。
RxJava follows the observer pattern in which an Observer (explained later) subscribes to an Observable which emits events/data and then reacts accordingly. The concepts in RxJava are best explained with the help of Marble diagrams. So here is one for you:
RxJava遵循观察者模式,在该模式中,观察者(稍后说明)订阅了一个观察者,该观察者发出事件/数据,然后做出相应的React。 RxJava中的概念最好借助Marble图进行解释。 因此,这里有一个适合您:
In ReactiveX, many instructions may execute in parallel and their results are later captured, in arbitrary order, by “observers.” Rather than calling a method, you define a mechanism for retrieving and transforming the data, in the form of an “Observable.” Then you subscribe an observer to it, at which point the previously-defined mechanism fires into action with the observer standing sentry to capture and respond to its emissions whenever they are ready.
在ReactiveX中,许多指令可以并行执行,并且其结果随后由“ 观察者 ”以任意顺序捕获。 无需调用方法,而是以“ 可观察的”形式定义一种用于检索和转换数据的机制。 ”然后,您向观察员订阅该观察员,这时,先前定义的机制将启动,观察员站岗,以随时准备捕获并响应其排放。
An advantage of this approach is that when you have a bunch of tasks that are not dependent on each other, you can start them all at the same time rather than waiting for each one to finish before starting the next one. That way, your entire bundle of tasks only takes as long to complete as the longest task in the bundle.
这种方法的优点是,当您有一堆彼此不依赖的任务时,可以同时启动所有任务,而不必等每个任务都完成才开始下一个任务。 这样,您整个任务捆绑包所需的时间与捆绑包中最长的任务一样长。
调度程序(重要) (Schedulers (important))
One of the super cool features of RxJava is that it provides for instant concurrency. Concurrency is really difficult to understand. Even today it is one of the most complex topics in computer science and is really hard to implement.
RxJava的超酷功能之一是它提供即时并发。 并发真的很难理解。 即使在今天,它仍然是计算机科学中最复杂的主题之一,并且确实很难实现。
The geniuses who wrote RxJava have abstracted all of these complexities away for us, giving us relatively simpler APIs to work with. RxJava handles concurrency with the help of Schedulers. In the RxJava routine, we have an operator named
编写RxJava的天才们为我们消除了所有这些复杂性,使我们可以使用相对简单的API。 RxJava在调度程序的帮助下处理并发。 在RxJava例程中,我们有一个名为
subscribeOn()
It basically says: Here is an observable and an observer, take them and establish their connection on this particular thread.
它基本上说: 这是一个可观察的对象和一个观察者,将它们放在该特定线程上并建立它们的连接。
All of this can be achieved with pure Java using Threads, Handlers, Executors etc, but Schedulers are just an elegant way of handling it.
所有这些都可以通过使用线程,处理程序,执行器等的纯Java来实现,但是调度程序只是一种优雅的处理方式。
Generally, most of the operations are delegated to the IO thread. But there are many other scheduler types. Here are some of the most commonly used:
通常,大多数操作都委托给IO线程。 但是还有许多其他调度程序类型。 以下是一些最常用的方法:
Schedulers.io(): used for non-computational IO tasks such as File Management, making network calls, database management etc. This thread pool is intended to be used for asynchronous tasks.
Schedulers.io():用于非计算IO任务,例如文件管理,进行网络调用,数据库管理等。此线程池旨在用于异步任务。
Schedulers.computation(): As the name suggests, it is intended to be used for computation-heavy tasks such as image processing, dataset processing etc. It has as many numbers of threads as the number of available processors. But you should be careful while using it as it can lead to degradation in performance due to context switching in threads.
Schedulers.computation():顾名思义,它旨在用于计算量大的任务,例如图像处理,数据集处理等。它具有与可用处理器数量一样多的线程数。 但是使用它时应小心,因为它可能会由于线程中的上下文切换而导致性能下降。
Schedulers.from(Executor ex): creates and returns a custom scheduler backed by a specific executor.
Schedulers.from(Executor ex):创建并返回由特定执行者支持的自定义调度程序。
Schedulers.mainThread(): Hey, I haven’t forgotten about you Android Devs ? This is provided by RxAndroid library and provides us with the main thread. Be careful not to perform long running tasks on this thread as it is synchronous and can lead to ANRs.
Schedulers.mainThread():嘿,我还没有忘记您的Android Dev? 这是由RxAndroid库提供的,并为我们提供了主线程。 注意不要在此线程上执行长时间运行的任务,因为它是同步的,并且可能导致ANR。
There is also an operator named
还有一个名为
observeOn()
As we saw above, subscribeOn() instructs the source Observable which thread to emit items on — this thread will push the emissions all the way to our Observer. However, if it encounters an observeOn() anywhere in the chain, it will switch and pass emissions using that Scheduler for the remaining (downstream) operations.
正如我们在上面看到的, subscribeOn()指示源Observable在哪个线程上发射项目-该线程将发射一直推到我们的Observer。 但是,如果它在链中的任何地方都遇到了一个observeOn(),它将使用该Scheduler切换并传递发射,以进行其余(下游)操作。
观察者/订阅者 (Observer/Subscriber)
As an artist needs an audience, the observable also needs someone to observe it while it emits items. There can be emissions without an observer (google hot and cold observables), but that’s a story for some other time.
当艺术家需要观众时,可观察者也需要有人在观察物品的同时对其进行观察。 可能没有观察员(谷歌的冷热观测值)会产生排放,但这是另一些故事了。
An observer subscribes to the observable with the help of the subscribe() method. As soon as the observer subscribes, it is ready to receive notifications from the observable.
观察者借助subscribe()方法订阅了可观察对象。 观察者订阅后,就可以接收来自可观察对象的通知。
It provides three methods to handle the notifications:
它提供了三种处理通知的方法:
onNext(): In this method, the notification is delivered to the subscriber without any errors.
onNext():在这种方法中,通知将毫无错误地传递给订户。
onError(): A throwable is sent to the subscriber in onError outlining the error.
onError():概述onError的onError中将throwable发送给订户。
onComplete(): This is called at the end when the source has finished emitting.
onComplete():在源完成发射时在最后调用。
Depending upon whether you were observing on the main thread or a separate thread, you’ll be getting the emissions in the onNext in the main thread or a new thread.
根据是在主线程上还是在单独的线程上进行观察,您将在主线程或新线程的onNext中获得发射。
When a Subscriber subscribes to a Publisher then in RxJava2, a Disposable instance is returned which can be used to cancel/dispose a Subscriber externally via Disposable::dispose().
当订阅服务器订阅发布服务器时,则在RxJava2中,将返回一个Disposable实例,该实例可用于通过Disposable :: dispose()在外部取消/处置订阅服务器。
Here is a diagram to help you understand this relationship better:
以下图表可帮助您更好地了解这种关系:
[caption id=”attachment_1032" align=”aligncenter” width=”1340"]
[标题ID =” attachment_1032” align =” aligncenter” width =“ 1340”]
Image Source [Mindorks][/caption]
图片来源[ Mindorks ] [/ caption]
我什至应该使用RxJava吗? (Should I even use RxJava?)
Instead of making my case verbally, I’ll leave it up to you to decide. Just go through the code below.
与其口头说明我,不如由我来决定。 只需通过下面的代码。
Java (Java)
List<Integer> temp = Arrays.asList(5,8,9,20,30,40);List<Integer> javaList = new ArrayList<>();
for(Integer i: temp){ if(i>10) javaList.add(i);}
RxJava的 (RxJava)
List<Integer> rxlist = Stream.of(5, 8, 9, 20, 30, 40).filter(x -> x > 10). collect(Collectors.toList());
Java (Java)
TPExecutor.execute(() -> api.getUserDetails(userId)) .runOnUIAfterBoth(TPExecutor.execute(() -> api.getUserPhoto(userId)), p -> { // Do your task });
RxJava的 (RxJava)
Observable.zip(api.getUserDetails2(userId), api.getUserPhoto2(userId), (details, photo) -> Pair.of(details, photo)) .subscribe(p -> { // Do your task. });
异步任务 (AsyncTask)
private class MyTask extends AsyncTask<String, Integer, Boolean>{ @Override protected Boolean doInBackground(String... paths) { for (int index = 0; index < paths.length; index++) { boolean result = copyFileToExternal(paths[index]);
if (result == true) { // update UI publishProgress(index); } else { // stop the background process return false; } }
return true; }
@Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); int count = values[0]; // this will update my textview to show the number of files copied myTextView.setText("Total files: " + count); }
@Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); if (result) { // display a success dialog ShowSuccessAlertDialog(); } else { // display a fail dialog ShowFailAlertDialog(); } }}
RxJava的 (RxJava)
Observable.fromArray(getPaths()) .map(path -> copyFileToExternal(path)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(aInteger -> Log.i("test", "update UI"), throwable -> ShowFailAlertDialog), () -> ShowSuccessAlertDialog());
You can see that the RxJava code is much more readable and concise (lambda expressions can get a little daunting if you are unfamiliar with them, but once you start using them, this code would feel like second nature to you). And there are many more examples where RxJava operators unleash their power over traditional Java programming.
您可以看到RxJava代码更具可读性和简洁性(如果您不熟悉lambda表达式,可能会有些畏缩,但是一旦开始使用它们,这对您来说就像是第二天性了)。 还有许多其他示例,其中RxJava操作员释放了他们对传统Java编程的控制权。
缺点 (Disadvantages)
I have not found any disadvantage in using RxJava up to this point — just that it has a really steep learning curve. If you aren’t already familiar with Observer pattern, Java 8 (not mandatory but really useful), lambdas etc, you’ll find RxJava code really intimidating.
到目前为止,我还没有发现使用RxJava的任何缺点-只是它的学习曲线非常陡峭 。 如果您还不熟悉Observer模式, Java 8 (不是强制性的,但确实有用),lambdas等,您会发现RxJava代码确实令人生畏。
But as you start patching your code with RxJava you’ll slowly start getting the hang of it and will realize that most of the constructs in RxJava remain the same.
但是,当您开始使用RxJava修补代码时,您将慢慢开始掌握它,并意识到RxJava中的大多数构造都保持不变。
This post has a complete list of resources to get you started.
Like what you read? Don’t forget to share this post on Facebook, Whatsapp, and LinkedIn.
喜欢你读的书吗? 不要忘记在Facebook , Whatsapp和LinkedIn上分享此帖子。
You can follow me on LinkedIn, Quora, Twitter, and Instagram where I answer questions related to Mobile Development, especially Android and Flutter.
您可以在LinkedIn , Quora , Twitter和Instagram上关注我,在那里我回答与移动开发(尤其是Android和Flutter)有关的问题 。
数据结构链表例程