Android Development

Google's android guide Home Contact

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.