CtrlK
BlogDocsLog inGet started
Tessl Logo

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

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.reactivex.rxjava2/rxandroid@2.1.x
Publish Source
CLI
Badge
tessl/maven-io-reactivex-rxjava2--rxandroid badge