41,99 €
Reactive Programming with Java and ReactiveX
The primary audience for this book is developers with at least a fundamental mastery of Java.
Some readers will likely be interested in RxJava to make programs more resilient, concurrent, and scalable. Others may be checking out reactive programming just to see what it is all about, and to judge whether it can solve any problems they may have.
RxJava is a library for composing asynchronous and event-based programs using Observable sequences for the JVM, allowing developers to build robust applications in less time.
Learning RxJava addresses all the fundamentals of reactive programming to help readers write reactive code, as well as teach them an effective approach to designing and implementing reactive libraries and applications.
Starting with a brief introduction to reactive programming concepts, there is an overview of Observables and Observers, the core components of RxJava, and how to combine different streams of data and events together. You will also learn simpler ways to achieve concurrency and remain highly performant, with no need for synchronization. Later on, we will leverage backpressure and other strategies to cope with rapidly-producing sources to prevent bottlenecks in your application. After covering custom operators, testing, and debugging, the book dives into hands-on examples using RxJava on Android as well as Kotlin.
This book will be different from other Rx books, taking an approach that comprehensively covers Rx concepts and practical applications.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 441
BIRMINGHAM - MUMBAI
Copyright © 2017 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: June 2017
Production reference: 1140617
ISBN 978-1-78712-042-6
www.packtpub.com
Author
Thomas Nield
Copy Editor
Stuti Srivastava
Reviewers
David Karnok
David Moten
Project Coordinator
Prajakta Naik
Commissioning Editor
Aaron Lazar
Proofreader
Safis Editing
Acquisition Editor
Denim Pinto
Indexer
Tejal Daruwale Soni
Content Development Editor
Siddhi Chavan
Graphics
Abhinash Sahu
Technical Editor
Pranali Badge
Production Coordinator
Shraddha Falebhai
Thomas Nield is a business consultant for Southwest Airlines in Schedule Initiatives, and a maintainer for RxJavaFX and RxKotlin. Early in his career, he became fascinated with technology and its role in business analytics. After becoming proficient in Java, Kotlin, Python, SQL, and reactive programming, he became an open source contributor as well as an author/speaker at O'Reilly Media. He is passionate about sharing what he learns and enabling others with new skill sets. He enjoys making technical content relatable and relevant to those unfamiliar with or intimidated by it.
Currently, Thomas is interested in data science, reactive programming, and the Kotlin language. You may find him speaking on these three subjects and how they can interconnect.
He has also authored the book Getting Started with SQL, by O'Reilly Media.
I am blessed to have great people in my life who have enabled everything I do, including this book. To all my family and friends who saw little of me for 6 months while I wrote this book, thank you for being so patient and understanding.
First, I want to thank my mom and dad. They have worked hard to ensure that I have the opportunities that I have today. My dad did everything he could to provide a better education for my brothers and me. Growing up, my mom always pushed me forward, even when I resisted; she taught me to never settle and always struggle past my limits.
There are so many people at my company, Southwest Airlines, who I have to thank--the leaders and colleagues in ground ops, revenue management, and network planning, who have taken risks to green-light my projects. They have embraced my unconventional approaches in leveraging technology to solve industry challenges. It is amazing to work for a company that continues to be a maverick and support a tradition started by an attorney, a Texas businessman, and a cocktail napkin.
I also want to thank the great folks at O’Reilly Media and Packt who continue to open doors for me to write and speak. Although I was approached by Packt to write this book, they probably would never have found me if it was not for O’Reilly and my previous book, Getting Started with SQL.
While he was not involved in this book or ReactiveX, I want to extend my gratitude to Edvin Syse, the creator and maintainer of TornadoFX. I joined his project in early 2016, and it is amazing how far it has come. Edvin’s work has helped me save a lot of my time and enabled me to pursue initiatives like this book. If you ever need to build JVM desktop apps quickly, Edvin’s work may change how you do so forever. More importantly, he is probably the nicest and most helpful person you will encounter in the open source community.
Finally, I want to thank the open source community for helping me shape this journey and what ultimately became this book. David Karnok and David Moten have been enormously patient with me over the years when I had questions about RxJava. David Karnok seems to have an infinite bandwidth, not only owning and maintaining RxJava, but also answering questions and being the project’s ambassador. David Moten also contributes to RxJava and is an Rx advocate for newbies and veterans alike, answering questions and helping anyone at any skill level. It is an honor to have them both review this book. I also want to thank Stepan Goncharov for checking my content on Android and everyone else in the OSS community who has been quick to share their knowledge and insights over the years.
David Karnok is the project lead and top contributor of RxJava. He is a PhD candidate in the field of production informatics. He is originally a mechanical engineer by trade who has picked up computer science along the way. He is currently a research assistant at the Engineering and Management Intelligence Research Lab under the Hungarian Academy of Sciences. He was also the first to port the historical Rx.NET library to Java back in 2011 (Reactive4Java)--2 years before Netflix started over again. Starting from late 2013, he contributed more than half of RxJava 1 and then designed, architected, and implemented almost all of RxJava 2 known today. In addition, he is perhaps the only person who does any research and development on reactive flows in terms of architecture, algorithms, and performance, of which, the major contribution to the field is the modern internals in RxJava 2 and Pivotal's Reactor Core 3. If one wants to know the in-depths of RxJava, Reactive-Streams, or reactive programming in general, David is the go-to "guru" worth listening to.
David is also a reviewer of the book, Learning Reactive Programming With Java 8, by Packt, and Reactive Programming with RxJava, by O'Reilly.
David Moten is a software developer, largely on JVM, who loves creating libraries for others and himself to use. Contributing to open source projects and participating in open source communities has been a source of enjoyment for him and a considerable education in recent years, with some really interesting complex problems in the RxJava project. RxJava itself has proven to be a huge boon, both in his workplace and outside of it, and David sees reactive programming growing in importance in mobile, backend, and frontend applications.
For support files and downloads related to your book, please visit www.PacktPub.com.
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.comand as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/1787120422.
If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
Thinking Reactively
A brief history of ReactiveX and RxJava
Thinking reactively
Why should I learn RxJava?
What we will learn in this book?
Setting up
Navigating the Central Repository
Using Gradle
Using Maven
A quick exposure to RxJava
RxJava 1.0 versus RxJava 2.0 - which one do I use?
When to use RxJava
Summary
Observables and Subscribers
The Observable
How Observables work
Using Observable.create()
Using Observable.just()
The Observer interface
Implementing and subscribing to an Observer
Shorthand Observers with lambdas
Cold versus hot Observables
Cold Observables
Hot Observables
ConnectableObservable
Other Observable sources
Observable.range()
Observable.interval()
Observable.future()
Observable.empty()
Observable.never()
Observable.error()
Observable.defer()
Observable.fromCallable()
Single, Completable, and Maybe
Single
Maybe
Completable
Disposing
Handling a Disposable within an Observer
Using CompositeDisposable
Handling Disposal with Observable.create()
Summary
Basic Operators
Suppressing operators
filter()
take()
skip()
takeWhile() and skipWhile()
distinct()
distinctUntilChanged()
elementAt()
Transforming operators
map()
cast()
startWith()
defaultIfEmpty()
switchIfEmpty()
sorted()
delay()
repeat()
scan()
Reducing operators
count()
reduce()
all()
any()
contains()
Collection operators
toList()
toSortedList()
toMap() and toMultiMap()
collect()
Error recovery operators
onErrorReturn() and onErrorReturnItem()
onErrorResumeNext()
retry()
Action operators
doOnNext(), doOnComplete(), and doOnError()
doOnSubscribe() and doOnDispose()
doOnSuccess()
Summary
Combining Observables
Merging
Observable.merge() and mergeWith()
flatMap()
Concatenation
Observable.concat() and concatWith()
concatMap()
Ambiguous
Zipping
Combine latest
withLatestFrom()
Grouping
Summary
Multicasting, Replaying, and Caching
Understanding multicasting
Multicasting with operators
When to multicast
Automatic connection
autoConnect()
refCount() and share()
Replaying and caching
Replaying
Caching
Subjects
PublishSubject
When to use Subjects
When Subjects go wrong
Serializing Subjects
BehaviorSubject
ReplaySubject
AsyncSubject
UnicastSubject
Summary
Concurrency and Parallelization
Why concurrency is necessary
Concurrency in a nutshell
Understanding parallelization
Introducing RxJava concurrency
Keeping an application alive
Understanding Schedulers
Computation
IO
New thread
Single
Trampoline
ExecutorService
Starting and shutting down Schedulers
Understanding subscribeOn()
Nuances of subscribeOn()
Understanding observeOn()
Using observeOn() for UI event threads
Nuances of observeOn()
Parallelization
unsubscribeOn()
Summary
Switching, Throttling, Windowing, and Buffering
Buffering
Fixed-size buffering
Time-based buffering
Boundary-based buffering
Windowing
Fixed-size windowing
Time-based windowing
Boundary-based windowing
Throttling
throttleLast() / sample()
throttleFirst()
throttleWithTimeout() / debounce()
Switching
Grouping keystrokes
Summary
Flowables and Backpressure
Understanding backpressure
An example that needs backpressure
Introducing the Flowable
When to use Flowables and backpressure
Use an Observable If...
Use a Flowable If...
Understanding the Flowable and Subscriber
The Subscriber
Creating a Flowable
Using Flowable.create() and BackpressureStrategy
Turning an Observable into a Flowable (and vice-versa)
Using onBackpressureXXX() operators
onBackPressureBuffer()
onBackPressureLatest()
onBackPressureDrop()
Using Flowable.generate()
Summary
Transformers and Custom Operators
Transformers
ObservableTransformer
FlowableTransformer
Avoiding shared state with Transformers
Using to() for fluent conversion
Operators
Implementing an ObservableOperator
FlowableOperator
Custom Transformers and operators for Singles, Maybes, and Completables
Using RxJava2-Extras and RxJava2Extensions
Summary
Testing and Debugging
Configuring JUnit
Blocking subscribers
Blocking operators
blockingFirst()
blockingGet()
blockingLast()
blockingIterable()
blockingForEach()
blockingNext()
blockingLatest()
blockingMostRecent()
Using TestObserver and TestSubscriber
Manipulating time with the TestScheduler
Debugging RxJava code
Summary
RxJava on Android
Creating the Android project
Configuring Retrolambda
Configuring RxJava and friends
Using RxJava and RxAndroid
Using RxBinding
Other RxAndroid bindings libraries
Life cycles and cautions using RxJava with Android
Summary
Using RxJava for Kotlin New
Why Kotlin?
Configuring Kotlin
Configuring Kotlin for Gradle
Configuring Kotlin for Maven
Configuring RxJava and RxKotlin
Kotlin basics
Creating a Kotlin file
Assigning properties and variables
Extension functions
Kotlin lambdas
Extension operators
Using RxKotlin
Dealing with SAM ambiguity
Using let() and apply()
Using let()
Using apply()
Tuples and data classes
Future of ReactiveX and Kotlin
Summary
Appendix
Introducing lambda expressions
Making a Runnable a lambda
Making a Supplier a lambda
Making a Consumer a lambda
Making a Function a lambda
Functional types
Mixing object-oriented and reactive programming
Materializing and Dematerializing
Understanding Schedulers
Reactive programming is more than a technology or library specification. It is an entirely new mindset in how we solve problems. The reason it is so effective and revolutionary is it does not structure our world as a series of states, but rather something that is constantly in motion. Being able to quickly capture the complexity and dynamic nature of movement (rather than state) opens up powerful new possibilities in how we represent things with code.
When I first learned Java and object-oriented programming, I felt it was useful, but not effective enough. Although OOP is useful, I believed it needed to be paired with something else to be truly productive, which is why I keep an eye on C# and Scala. Only a few years later, Java 8 came out, and I put functional programming into practice for the first time.
However, something was still missing. I became fascinated with the idea of a value notifying another value of its change, and an event triggering another event in a domino effect. Was there not a way to model events in a fluent and functional way, much like Java 8 Streams? When I voiced this idea one day, somebody introduced me to reactive programming. What I was looking for was the RxJava Observable, which, at first glance, looked a lot like a Java 8 Stream. The two look and feel similar, but the Observable pushes not just data but also events. At that moment, I found exactly what I was looking for.
For me, as well as many others, a challenge in learning RxJava is the lack of documentation and literature. I was often left experimenting, asking questions on Stack Overflow, and trawling obscure issues on GitHub to become knowledgeable. As I used RxJava heavily for some business problems at work, I wrote several blog articles, sharing my discoveries on topics such as parallelization and concurrency. To my surprise, these articles exploded with traffic. Perhaps this should not have been surprising since these topics were sparsely documented anywhere else. When Packt approached me to write my second book, Learning RxJava, I jumped at the opportunity despite the work involved. Maybe, just maybe, this book can solve the documentation problem once and for all. Every fundamental concept, use case, helpful trick, and "gotcha" can be made accessible, and RxJava will no longer be considered an "advanced topic." I believe RxJava should be made accessible to professional developers of all skill levels, as it effectively makes hard problems easy and easy problems even easier. It may require a bit more abstract understanding, but the immediate productivity gained makes this small hurdle worthwhile.
As far as I know, this is the first published book covering RxJava 2.0, which has many major differences from RxJava 1.0. This book you are reading now is the comprehensive, step-by-step guide that I wish I had. It strives to not cut any corners or present code without thorough explanation. I hope it helps you quickly find value in RxJava, and you become successful in applying it to all your endeavors. If you have any concerns, feedback, or comments, you are welcome to reach out to me at [email protected].
Good luck!
Thomas Nield
Chapter 1, Thinking Reactively, introduces you to RxJava.
Chapter 2, Observables and Subscribers, talks about the core types in RxJava, including the Observable and Observer.
Chapter 3, Basic Operators, gives you a thorough introduction to the core operators that allow you to express logic quickly and make RxJava productive.
Chapter 4, Combining Observables, teaches you how to usefully combine multiple Observable sources together in a variety of ways.
Chapter 5, Multicasting, Replaying, and Caching, consolidates streams to prevent redundant work with multiple Observers, as well as replay and cache emissions.
Chapter 6, Concurrency and Parallelization, helps you discover how RxJava flexibly and powerfully enables concurrency in your application.
Chapter 7, Switching, Throttling, Windowing, and Buffering, develops strategies to cope with rapidly-producing Observables without backpressure.
Chapter 8, Flowables and Backpressure, utilizes the Flowable to leverage backpressure and keep producers from out-pacing consumers.
Chapter 9, Transformers and Custom Operators, teaches you how to reuse reactive logic and create your own RxJava operators.
Chapter 10, Testing and Debugging, leverages effective tools to test and debug your RxJava code bases.
Chapter 11, RxJava on Android, teaches you how to apply your RxJava knowledge and RxAndroid extensions to streamline your Android apps.
Chapter 12, Using RxJava for Kotlin New, takes advantage of Kotlin’s language features to enable expressive patterns with RxJava.
We will be using Java 8, so Oracle’s JDK 1.8 will be required. You will need an environment to write and compile your Java code (I recommend Intellij IDEA), and preferably a build automation system such as Gradle or Maven. Later in this book, we will use Android Studio.
Everything you need in this book should be free to use and not require commercial or personal licensing.
This book is for Java programmers who have a fundamental grasp of object-oriented programing and core Java features. You should be familiar with variables, types, classes, properties, methods, generics, inheritance, interfaces, and static classes/properties/methods. In the Java standard library, you should at least be familiar with collections (including Lists, Sets, and Maps) as well as object equality (hashcode()/equals()). If any of these topics sound unfamiliar, you may want to read Java: A Beginner’s Guide by Herbert Schildt to learn the fundamentals of Java. Also, Effective Java (2nd Edition) by Joshua Bloch is a classic book that should be on every Java developer’s shelf. This book strives to use the best practices cited by Bloch.
You do not need to be familiar with concurrency as a prerequisite. This topic will be covered from an RxJava perspective.
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "We can also use several operators betweenObservableand Observerto transform each pushed item or manipulate them in some way".
A block of code is set as follows:
import
io.reactivex.
Observable
;
public class
Launcher
{
public static void
main
(
String
[]
args
) {
Observable
<
String
>
myStrings
Observable
.
just
(
"Alpha"
,
"Beta"
,
"Gamma"
,
"Delta"
,
"Epsilon"
);
}
}
Any output is written as follows:
Alpha Beta Gamma Delta Epsilon
New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "You also have the option to use Maven, and you can view the appropriate configuration inThe Central Repositoryby selecting theApache Maven configuration information."
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.
To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
You can download the code files by following these steps:
Log in or register to our website using your e-mail address and password.
Hover the mouse pointer on the
SUPPORT
tab at the top.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on
Code Download
.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR / 7-Zip for Windows
Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux
The code bundle for the book is also hosted on GitHub athttps://github.com/PacktPublishing/Learning-RxJava. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at [email protected] with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
It is assumed you are fairly comfortable with Java and know how to use classes, interfaces, methods, properties, variables, static/nonstatic scopes, and collections. If you have not done concurrency or multithreading, that is okay. RxJava makes these advanced topics much more accessible.
Have your favorite Java development environment ready, whether it is Intellij IDEA, Eclipse, NetBeans, or any other environment of your choosing. I will be using Intellij IDEA, although it should not matter or impact the examples in this book. I recommend that you have a build automation system as well such as Gradle or Maven, which we will walk through shortly.
Before we dive deep into RxJava, we will cover some core topics first:
A brief history of Reactive Extensions and RxJava
Thinking reactively
Leveraging RxJava
Setting up your first RxJava project
Building your first reactive applications
Differences between RxJava 1.0 and RxJava 2.0
As developers, we tend to train ourselves to think in counter-intuitive ways. Modeling our world with code has never been short of challenges. It was not long ago that object-oriented programming was seen as the silver bullet to solve this problem. Making blueprints of what we interact with in real life was a revolutionary idea, and this core concept of classes and objects still impacts how we code today. However, business and user demands continued to grow in complexity. As 2010 approached, it became clear that object-oriented programming only solved part of the problem. Classes and objects do a great job of representing an entity with properties and methods, but they become messy when they need to interact with each other in increasingly complex (and often unplanned) ways. Decoupling patterns and paradigms emerged, but this yielded an unwanted side effect of growing amounts of boilerplate code. In response to these problems, functional programming began to make a comeback, not to replace object-oriented programming, but rather to complement it and fill this void. Reactive programming, a functional event-driven programming approach, began to receive special attention. A couple of reactive frameworks emerged ultimately, including Akka and Sodium. But at Microsoft, a computer scientist named Erik Meijer created a reactive programming framework for .NET called Reactive Extensions. In a matter of years, Reactive Extensions (also called ReactiveX or Rx) was ported to several languages and platforms, including JavaScript, Python, C++, Swift, and Java, of course. ReactiveX quickly emerged as a cross-language standard to bring reactive programming into the industry. RxJava, the ReactiveX port for Java, was created in large part by Ben Christensen from Netflix and David Karnok. RxJava 1.0 was released in November 2014, followed by RxJava 2.0 in November 2016. RxJava is the backbone to other ReactiveX JVM ports, such as RxScala, RxKotlin, and RxGroovy. It has become a core technology for Android development and has also found its way into Java backend development. Many RxJava adapter libraries, such as RxAndroid (https://github.com/ReactiveX/RxAndroid), RxJava-JDBC (https://github.com/davidmoten/rxjava-jdbc), RxNetty (https://github.com/ReactiveX/RxNetty), and RxJavaFX (https://github.com/ReactiveX/RxJavaFX) adapted several Java frameworks to become reactive and work with RxJava out of the box. This all shows that RxJava is more than a library. It is part of a greater ReactiveX ecosystem that represents an entire approach to programming. The fundamental idea of ReactiveX is that events are data and data are events. This is a powerful concept that we will explore later in this chapter, but first, let's step back and look at the world through the reactive lens.
Suspend everything you know about Java (and programming in general) for a moment, and let's make some observations about our world. These may sound like obvious statements, but as developers, we can easily overlook them. Bring your attention to the fact that everything is in motion. Traffic, weather, people, conversations, financial transactions, and so on are all moving. Technically, even something stationary as a rock is in motion due to the earth's rotation and orbit. When you consider the possibility that everything can be modeled as in motion, you may find it a bit overwhelming as a developer. Another observation to note is that these different events are happening concurrently. Multiple activities are happening at the same time. Sometimes, they act independently, but other times, they can converge at some point to interact. For instance, a car can drive with no impact on a person jogging. They are two separate streams of events. However, they may converge at some point and the car will stop when it encounters the jogger. If this is how our world works, why do we not model our code this way?. Why do we not model code as multiple concurrent streams of events or data happening at the same time? It is not uncommon for developers to spend more time managing the states of objects and doing it in an imperative and sequential manner. You may structure your code to execute Process 1, Process 2, and then Process 3, which depends on Process 1 and Process 2. Why not kick-off Process 1 and Process 2 simultaneously, and then the completion of these two events immediately kicks-off Process 3? Of course, you can use callbacks and Java concurrency tools, but RxJava makes this much easier and safer to express. Let's make one last observation. A book or music CD is static. A book is an unchanging sequence of words and a CD is a collection of tracks. There is nothing dynamic about them. However, when we read a book, we are reading each word one at a time. Those words are effectively put in motion as a stream being consumed by our eyes. It is no different with a music CD track, where each track is put in motion as sound waves and your ears are consuming each track. Static items can, in fact, be put in motion too. This is an abstract but powerful idea because we made each of these static items a series of events. When we level the playing field between data and events by treating them both the same, we unleash the power of functional programming and unlock abilities you previously might have thought impractical. The fundamental idea behind reactive programming is that events are data and data are events. This may seem abstract, but it really does not take long to grasp when you consider our real-world examples. The runner and car both have properties and states, but they are also in motion. The book and CD are put in motion when they are consumed. Merging the event and data to become one allows the code to feel organic and representative of the world we are modeling.
ReactiveX and RxJava paints a broad stroke against many problems programmers face daily, allowing you to express business logic and spend less time engineering code. Have you ever struggled with concurrency, event handling, obsolete data states, and exception recovery? What about making your code more maintainable, reusable, and evolvable so it can keep up with your business? It might be presumptuous to call reactive programming a silver bullet to these problems, but it certainly is a progressive leap in addressing them. There is also growing user demand to make applications real time and responsive. Reactive programming allows you to quickly analyse and work with live data sources such as Twitter feeds or stock prices. It can also cancel and redirect work, scale with concurrency, and cope with rapidly emitting data. Composing events and data as streams that can be mixed, merged, filtered, split, and transformed opens up radically effective ways to compose and evolve code. In summary, reactive programming makes many hard tasks easy, enabling you to add value in ways you might have thought impractical earlier. If you have a process written reactively and you discover that you need to run part of it on a different thread, you can implement this change in a matter of seconds. If you find network connectivity issues crashing your application intermittently, you can gracefully use reactive recovery strategies that wait and try again. If you need to inject an operation in the middle of your process, it is as simple as inserting a new operator. Reactive programming is broken up into modular chain links that can be added or removed, which can help overcome all the aforementioned problems quickly. In essence, RxJava allows applications to be tactical and evolvable while maintaining stability in production.
As stated earlier, RxJava is the ReactiveX port for Java. In this book, we will focus primarily on RxJava 2.0, but I will call out significant differences in RxJava 1.0. We will place priority on learning to think reactively and leverage the practical features of RxJava. Starting with a high-level understanding, we will gradually move deeper into how RxJava works. Along the way, we will learn about reactive patterns and tricks to solve common problems programmers encounter. In Chapter 2, The Observable and Subscribers,Chapter 3, Basic Operators, and Chapter 4, Combining Observables, we will cover core Rx concepts with Observable, Observer, and Operator. These are the three core entities that make up RxJava applications. You will start writing reactive programs immediately and have a solid knowledge foundation to build on for the rest of the book. Chapter 5, Multicasting, Replaying, and Caching, and Chapter 6, Concurrency and Parallelization, will explore more of the nuances of RxJava and how to effectively leverage concurrency.
In Chapter 7, Switching, Throttling, Windowing, and Buffering and Chapter 8, Flowables and Backpressure, we will learn about the different ways to cope with reactive streams that produce data/events faster than they can be consumed.
Finally, Chapter 9, Transformers and Custom Operators, Chapter 10, Testing and Debugging, Chapter 11, RxJava on Android, and Chapter 12, Using RxJava with Kotlin New, will touch on several miscellaneous (but essential) topics including custom operators as well as how to use RxJava with testing frameworks, Android, and the Kotlin language.
There are two co-existing versions of RxJava currently: 1.0 and 2.0. We will go through some of the major differences later and discuss which version you should use.
RxJava 2.0 is a fairly lightweight library and comes just above 2 Megabytes (MBs) in size. This makes it practical for Android and other projects that require a low dependency overhead. RxJava 2.0 has only one dependency, called Reactive Streams ( http://www.reactive-streams.org/), which is a core library (made by the creators of RxJava) that sets a standard for asynchronous stream implementations, one of which is RxJava 2.0.
It may be used in other libraries beyond RxJava and is a critical effort in the standardization of reactive programming on the Java platform. Note that RxJava 1.0 does not have any dependencies, including Reactive Streams, which was realized after 1.0.
If you are starting a project from scratch, try to use RxJava 2.0. This is the version we will cover in this book, but I will call out significant differences in 1.0. While RxJava 1.0 will be supported for a good while due to countless projects using it, innovation will likely only continue onward in RxJava 2.0. RxJava 1.0 will only get maintenance and bug fixes.
Both RxJava 1.0 and 2.0 run on Java 1.6+. In this book, we will use Java 8, and it is recommended that you use a minimum of Java 8 so you can use lambdas out of the box. For Android, there are ways to leverage lambdas in earlier Java versions that will be addressed later. But weighing the fact that Android Nougat uses Java 8 and Java 8 has been out since 2014, hopefully, you will not have to do any workarounds to leverage lambdas.
To bring in RxJava as a dependency, you have a few options. The best place to start is to go to The Central Repository (search http://search.maven.org/) and search for rxjav. You should see RxJava 2.0 and RxJava 1.0 as separate repositories at the top of the search results, as shown in the following screenshot:
At the time of writing, RxJava 2.0.2 is the latest version for RxJava 2.0 and RxJava 1.2.3 is the latest for RxJava 1.0. You can download the latest JAR file for either by clicking the JAR links in the far right under the Download column. You can then configure your project to use the JAR file.
However, you might want to consider using Gradle or Maven to automatically import these libraries into your project. This way, you can easily share and store your code project (through GIT or other version control systems) without having to download and configure RxJava manually into it each time. To view the latest configurations for Maven, Gradle, and several other build automation systems, click on the version number for either of the repositories, as highlighted in the following screenshot:
You also have the option to use Maven, and you can view the appropriate configuration in The Central Repository by selecting the Apache Maven configuration information, as shown in the following screenshot:
You can then copy and paste the <dependency> block containing the RxJava configuration and paste it inside a <dependencies>block in your pom.xml file. Rebuild your project, and you should now have RxJava set up as a dependency. The x.y.z version number corresponds to the desired RxJava version that you want to use:
<
project
>
<
modelVersion
>
4.0.0
</
modelVersion
>
<
groupId
>
org.nield
</
groupId
>
<
artifactId
>
mavenrxtest
</
artifactId
>
<
version
>
1.0
</
version
>
<
dependencies
>
<
dependency
>
<
groupId
>
io.reactivex.rxjava2
</
groupId
>
<
artifactId
>
rxjava
</
artifactId
>
<
version
>
x.y.z
</
version
>
</
dependency
>
</
dependencies
>
</
project
>
As stated earlier, you are encouraged to use RxJava 2.0 if you can. It will continue to grow and receive new features, while RxJava 1.0 will be maintained for bug fixes. However, there are other considerations that may lead you to use RxJava 1.0.
If you inherit a project that is already using RxJava 1.0, you will likely continue using that until it becomes feasible to refactor to 2.0. You can also check out David Akarnokd's RxJava2Interop project (https://github.com/akarnokd/RxJava2Interop), which converts Rx types from RxJava 1.0 to RxJava 2.0 and vice versa. After you finish this book, you may consider using this library to leverage RxJava 2.0 even if you have the RxJava 1.0 legacy code.
In RxJava, there are several libraries to make several Java APIs reactive and plug into RxJava seamlessly. Just to name a few, these libraries include RxJava-JDBC, RxAndroid, RxJava-Extras, RxNetty, and RxJavaFX. At the time of writing this, only RxAndroid and RxJavaFX have been fully ported to RxJava 2.0 (although many other libraries are following). By the time you are reading this, all major RxJava extension libraries will hopefully be ported to RxJava 2.0.
You will also want to prefer RxJava 2.0 because it was built on much of the hindsight and wisdom gained from RxJava 1.0. It has better performance, simpler APIs, a cleaner approach to backpressure, and a bit more safety when hacking together your own operators.
A common question ReactiveX newcomers ask is what circumstances warrant a reactive approach? Do we always want to use RxJava? As someone who has been living and breathing reactive programming for a while, I have learned that there are two answers to this question:
The first answer is when you first start out: yes! You always want to take a reactive approach. The only way to truly become a master of reactive programming is to build reactive applications from the ground up. Think of everything as Observable and always model your program in terms of data and event flows. When you do this, you will leverage everything reactive programming has to offer and see the quality of your applications go up significantly.
The second answer is that when you become experienced in RxJava, you will find cases where RxJava may not be appropriate. There will occasionally be times where a reactive approach may not be optimal, but usually, this exception applies to only part of your code. Your entire project itself should be reactive. There may be parts that are not reactive and for good reason. These exceptions only stand out to a trained Rx veteran who sees that returning List<String> is perhaps better than returning Observable<String>. Rx greenhorns should not worry about when something should be reactive versus something not reactive. Over time, they will start to see cases where the benefits of Rx are marginalized, and this is something that only comes with experience.
So for now, no compromises. Go reactive all the way!
In this chapter, we learned how to look at the world in a reactive way. As a developer, you may have to retrain yourself from a traditional imperative mindset and develop a reactive one. Especially if you have done imperative, object-oriented programming for a long time, this can be challenging. But the return on investment will be significant as your applications will become more maintainable, scalable, and evolvable. You will also have faster turn around and more legible code.
We also covered how to configure a RxJava project using Gradle or Maven and what decisions should drive whether you should choose RxJava 2.0 versus RxJava 1.0. We also got a brief introduction to reactive code and how Observable works through push-based iteration. By the time you finish this book, you will hopefully find reactive programming intuitive and easy to reason with. I hope you find that RxJava not only makes you more productive, but also helps you take on tasks you hesitated to do earlier. So let's get started!
We already got a glimpse into the Observable and how it works in Chapter 1, Thinking Reactively. You probably have many questions on how exactly it operates and what practical applications it holds. This chapter will provide a foundation for understanding how an Observable works as well as the critical relationship it has with the Observer. We will also cover several ways to create an Observable as well make it useful by covering a few operators. To make the rest of the book flow smoothly, we will also cover all critical nuances head-on to build a solid foundation and not leave you with surprises later.
Here is what we will cover in this chapter:
The
Observable
The
Observer
Other
Observable
factories
Single
,
Completable
, and
Maybe
Disposable
As introduced in Chapter 1, Thinking Reactively, the Observable is a push-based, composable iterator. For a given Observable<T>, it pushes items (called emissions) of type T through a series of operators until it finally arrives at a final Observer, which consumes the items. We will cover several ways to create an Observable, but first, let's dive into how an Observable works through its onNext(), onCompleted(), and onError() calls.
Before we do anything else, we need to study how an Observable sequentially passes items down a chain to an Observer. At the highest level, an