RxJava and RxAndroid
Rx is a reactive extension. Reactive programming combines the principles of the Observer Pattern, Iterator Pattern, and Functional Programming. It focuses on asynchronous data streams and propagating changes through those streams. RxAndroid is a library built on top of RxJava, adding a few classes to make it more suitable for the Android platform. Specifically, it provides the Android application's main thread (or any given looper) as an RxJava scheduler, enabling developers to decide on which thread specific code should execute.
In reactive programming, data is modeled as streams, which are sequences of values arriving over time. For example, a stream could represent button clicks, typing events, sensor readings, GPS variations, network responses, location changes, gyroscope data, remote network events, hardware events, or sensor updates. Streams can be combined and transformed using various operators to produce new streams, which can then be processed or used to drive application behavior.
Key terms to understand RxJava (or its extension RxAndroid) are:
- Observable: Emits a stream of data.
- Observer or Subscriber: Consumes the stream. Multiple observers can subscribe to a single observable.
- Operators: Modify, transform, and manipulate emissions from the observable before they are received by the observer.
- Schedulers: Define the threads where observable operations are performed.
Observables generate data, and observers are informed of state changes. Operators transform the data produced by observables or other operators. Subscribers handle the results of these transformations and react accordingly. Subscriptions allow tracking of the operation's completion or cancellation. Schedulers determine where the work is done and where the results are processed.
RxJava and RxAndroid can simplify writing efficient, responsive, and scalable Android apps. However, they can also introduce complexity, so it's important to weigh the benefits against the costs when deciding whether to use these libraries in a project.
RxAndroid Example Code
User.java
public class User { private String name; public User(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
UserService.java
public class UserService { public Observable> getUsers() { return Observable.fromCallable(() -> { List
users = new ArrayList<>(); users.add(new User("A")); users.add(new User("B")); users.add(new User("C")); return users; }).delay(2, TimeUnit.SECONDS); } }
MainActivity.java
public class MainActivity extends AppCompatActivity { private TextView nameTextView; private Disposable disposable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nameTextView = findViewById(R.id.nameTextView); UserService userService = new UserService(); disposable = userService.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { disposable = d; } @Override public void onNext(@NonNull List
users) { nameTextView.setText(users.get(0).getName()); } @Override public void onError(@NonNull Throwable e) { Toast.makeText(MainActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onComplete() { // No action required } }); } @Override protected void onDestroy() { super.onDestroy(); if (disposable != null && !disposable.isDisposed()) { disposable.dispose(); } } }
This example uses a single TextView to display the name of the first user in the list. The getUsers()
method in UserService
returns an observable.
The MainActivity
class uses the subscribe()
method to subscribe to the observable. When the observable emits a list of users, the onNext()
method is called,
and the name of the first user in the list is displayed in the TextView. The onError()
method handles errors, and the onComplete()
method is called when the observable completes.
The disposable returned by subscribe()
is stored in the disposable
field and is disposed of in the onDestroy()
method to prevent memory leaks.