or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/maven-io-reactivex-rxjava2--rxandroid

Android specific bindings for RxJava 2 providing schedulers for main thread and Looper-based scheduling

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.reactivex.rxjava2/rxandroid@2.1.x

To install, run

npx @tessl/cli install tessl/maven-io-reactivex-rxjava2--rxandroid@2.1.0

index.mddocs/

RxAndroid

RxAndroid provides Android-specific bindings for RxJava 2, offering schedulers for main thread execution and Looper-based scheduling. This minimal library adds essential Android integration to RxJava's reactive streams, making it easy to handle UI updates and background processing in Android applications.

Package Information

  • Package Name: io.reactivex.rxjava2:rxandroid
  • Package Type: Maven (Android AAR)
  • Language: Java
  • Version: 2.1.1
  • Installation: Add to your build.gradle dependencies: implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
  • Minimum SDK: Android API level 9
  • License: Apache-2.0

Core Imports

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.android.MainThreadDisposable;
import io.reactivex.android.plugins.RxAndroidPlugins;
import io.reactivex.Scheduler;
import android.os.Looper;

Basic Usage

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

// Schedule work on background thread and observe results on main thread
Observable.fromCallable(() -> {
    // Background work (e.g., network call, database operation)
    return processData();
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
    // Update UI on main thread
    updateUI(result);
});

// Custom Looper scheduling
HandlerThread handlerThread = new HandlerThread("Background");
handlerThread.start();
Scheduler customScheduler = AndroidSchedulers.from(handlerThread.getLooper());

Observable.just("data")
    .observeOn(customScheduler)
    .subscribe(data -> {
        // Process on custom thread
    });

Capabilities

Main Thread Scheduling

Android-specific scheduler that executes actions on the main UI thread.

/**
 * Returns a Scheduler which executes actions on the Android main thread.
 * Thread-safe and can be called from any thread.
 */
public static Scheduler mainThread();

Looper-Based Scheduling

Create schedulers that execute on specific Android Loopers.

/**
 * Returns a Scheduler which executes actions on the specified Looper.
 * @param looper the Looper to schedule actions on
 * @throws NullPointerException if looper is null
 */
public static Scheduler from(Looper looper);

/**
 * Returns a Scheduler which executes actions on the specified Looper with async messaging option.
 * @param looper the Looper to schedule actions on
 * @param async if true, uses async messaging on API >= 16 to avoid VSYNC locking.
 *              Automatically set to false on API < 16. On API 16-21, validates that
 *              Message.setAsynchronous() is available before enabling async messaging.
 * @throws NullPointerException if looper is null
 */
public static Scheduler from(Looper looper, boolean async);

Usage Example:

// Create background thread with custom Looper
HandlerThread backgroundThread = new HandlerThread("MyBackground");
backgroundThread.start();

// Schedule work on custom Looper
Scheduler customScheduler = AndroidSchedulers.from(backgroundThread.getLooper());
Observable.just("work")
    .observeOn(customScheduler)
    .subscribe(item -> {
        // Executes on custom background thread
    });

// Using async messaging (API 16+)
Scheduler asyncScheduler = AndroidSchedulers.from(backgroundThread.getLooper(), true);

// Note: AndroidSchedulers uses HandlerScheduler internally for all Looper-based scheduling

Main Thread Disposable

Abstract base class for creating disposables that ensure their disposal actions run on the main thread.

/**
 * Abstract class implementing Disposable with main thread disposal guarantee.
 * Useful for UI-related subscriptions that need cleanup on the main thread.
 */
public abstract class MainThreadDisposable implements Disposable {
    
    /**
     * Verify that the calling thread is the Android main thread.
     * Commonly used as precondition check in custom observables.
     * @throws IllegalStateException when called from any thread other than main thread
     */
    public static void verifyMainThread();
    
    /**
     * Returns whether this Disposable is disposed.
     */
    public final boolean isDisposed();
    
    /**
     * Disposes this Disposable, ensuring onDispose() runs on main thread.
     * Thread-safe - can be called from any thread.
     */
    public final void dispose();
    
    /**
     * Called when disposal occurs, guaranteed to execute on main thread.
     * Subclasses must implement this method to perform cleanup.
     */
    protected abstract void onDispose();
}

Usage Example:

public class CustomObservable extends Observable<String> {
    @Override
    protected void subscribeActual(Observer<? super String> observer) {
        // Verify we're on main thread for UI access
        MainThreadDisposable.verifyMainThread();
        
        // Set up some UI listener or resource
        setupUIListener();
        
        observer.onSubscribe(new MainThreadDisposable() {
            @Override
            protected void onDispose() {
                // Cleanup UI resources - guaranteed to run on main thread
                cleanupUIListener();
            }
        });
        
        observer.onNext("data");
        observer.onComplete();
    }
}

Plugin System

Customization hooks for RxAndroid scheduler behavior, useful for testing and debugging.

/**
 * Sets a handler to customize main thread scheduler initialization.
 * @param handler function to transform scheduler initialization
 */
public static void setInitMainThreadSchedulerHandler(Function<Callable<Scheduler>, Scheduler> handler);

/**
 * Initializes main thread scheduler with optional handler transformation.
 * @param scheduler callable that provides default scheduler
 * @throws NullPointerException if scheduler is null
 * @return transformed scheduler or default if no handler set
 */
public static Scheduler initMainThreadScheduler(Callable<Scheduler> scheduler);

/**
 * Sets a handler to customize main thread scheduler instances.
 * @param handler function to transform scheduler instances
 */
public static void setMainThreadSchedulerHandler(Function<Scheduler, Scheduler> handler);

/**
 * Applies main thread scheduler handler if set.
 * @param scheduler scheduler to potentially transform
 * @throws NullPointerException if scheduler is null
 * @return transformed scheduler or original if no handler set
 */
public static Scheduler onMainThreadScheduler(Scheduler scheduler);

/**
 * Returns current init handler.
 * @return handler function or null if not set
 */
public static Function<Callable<Scheduler>, Scheduler> getInitMainThreadSchedulerHandler();

/**
 * Returns current main thread handler.
 * @return handler function or null if not set
 */
public static Function<Scheduler, Scheduler> getOnMainThreadSchedulerHandler();

/**
 * Removes all handlers and resets to default behavior.
 */
public static void reset();

Usage Example:

// Replace main thread scheduler for testing
RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> Schedulers.trampoline());

// Custom initialization
RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> {
    return new CustomTestScheduler();
});

// Reset to defaults (typically in test teardown)
RxAndroidPlugins.reset();

Types

// From RxJava 2 - key types used by RxAndroid
interface Scheduler {
    Disposable scheduleDirect(Runnable run);
    Worker createWorker();
}

interface Disposable {
    void dispose();
    boolean isDisposed();
}

interface Function<T, R> {
    R apply(T t) throws Exception;
}

// From Android SDK
class Looper {
    static Looper getMainLooper();
    static Looper myLooper();
}

Error Handling

RxAndroid follows RxJava's error handling patterns:

  • NullPointerException: Thrown when null parameters are passed to AndroidSchedulers.from() or RxAndroidPlugins methods
  • IllegalStateException: Thrown by MainThreadDisposable.verifyMainThread() when called from non-main thread
  • All exceptions propagate through RxJava's plugin system and can be handled using RxJavaPlugins.setErrorHandler()

Thread Safety

  • All public static methods in AndroidSchedulers and RxAndroidPlugins are thread-safe
  • MainThreadDisposable.dispose() is thread-safe using atomic operations
  • Plugin handlers are stored in volatile fields for safe publication across threads