• This repository has been archived on 23/May/2020
  • Stars
    star
    322
  • Rank 130,398 (Top 3 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 10 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

[Deprecated] Handles Android's activity lifecyle for rxjava's Observable

[Deprecated]

There are better solutions out there, would recommend using LiveData or AutoDispose with rx.

rxloader

Asynchronous operations in Android are very hard to get right due to the Activity lifecycle. AsyncTasks don't handle any of it making them difficult to use. Loaders handle many things for you, but have a clunky api and fall down anytime you want to do anything more complex than loading data immediately when the Activity or Fragment is shown.

This library builds upon rxjava to handle all these things for you with an easy-to-use api.

Install

Gradle

repositories {
  mavenCentral()
}

dependencies {
  implementation 'me.tatarka.rxloader:rxloader:1.1.0'
}

Maven

<dependency>
  <groupId>me.tatarka.rxloader</groupId>
  <artifactId>rxloader</artifactId>
  <version>1.1.0</version>
</dependency>

Usage

The sample app shows some common use cases of handling observables.

Here is a simple example of loading data as soon as your activity starts.

public class MyActivity extends Activity {
  private RxLoaderManager loaderManager;

  public void onCreate(Bundle savedState) {
    // If you are using the support library, 
    // use RxLoaderManagerCompat.get(this) instead.
    loaderManager = RxLoaderManager.get(this);

    loaderManager.create(
      asyncThatReturnsObservable(),
      new RxLoaderObserver<Result>() {
        @Override
        public void onStarted() {
          // Show your progress indicator.
        }

        @Override
        public void onNext(Result result) {
          // Hide your progress indicator and show the result.
        }

        @Override
        public void onError(Throwable error) {
          // Hide your progress indicator and show that there was an error.
        }
      }
    ).start(); // Make sure you call this to kick things off.
  }
}

Or in a fragment

public class MyFragment extends Fragment {
  private RxLoaderManager loaderManager;

  public void onViewCreated(View view, Bundle savedInstanceState) {
    // If you are using the support library, 
    // use RxLoaderManagerCompat.get(this) instead.
    loaderManager = RxLoaderManager.get(this);

    loaderManager.create(
      asyncThatReturnsObservable(),
      new RxLoaderObserver<Result>() {
        @Override
        public void onStarted() {
          // Show your progress indicator.
        }

        @Override
        public void onNext(Result result) {
          // Hide your progress indicator and show the result.
        }

        @Override
        public void onError(Throwable error) {
          // Hide your progress indicator and show that there was an error.
        }
      }
    ).start(); // Make sure you call this to kick things off.
  }
}

All observer callbacks run on the UI thread. If the Activity or Fragment is destroyed, the callbacks will not be called. If there is a configuration change, the relevant callbacks will be called again.

Here is an example of loading and reloading on a button press. Try doing this with loaders!

public class MyActivity extends Activity {
  private RxLoaderManager loaderManager;

  public void onCreate(Bundle savedState) {
    loaderManager = RxLoaderManager.get(this);

    final RxLoader<Result> myLoader = loaderManager.create(
      asyncThatReturnsObservable(),
      new RxLoaderObserver<Result>() {
        @Override
        public void onStarted() {
          // Show your progress indicator.
        }

        @Override
        public void onNext(Result result) {
          // Hide your progress indicator and show the result.
        }

        @Override
        public void onError(Throwable error) {
          // Hide your progress indicator and show that there was an error.
        }
      }
    );

    findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View button) {
        myLoader.restart();
      }
    });
  }
}

Note that the loader is still created in onCreate() and not on the button callback. This is necessary to handle configuration changes properly if the button was pressed first.

Passing arguments

If you want to pass arguments to your observable, you can use one of the overloads that takes a Func1<Arg, Observable<T>> or Func2<Arg1, Arg2, Observable<T>>.

final RxLoader1<String, String> inputLoader = loaderManager.create(
  new Func1<String, Observable<String>>() {
    @Override
    public Observable<String> call(final String input) {
      return asyncMethod(input);
    }
  },
  new RxLoaderObserver<String>() {
    @Override
    public void onStarted() {
      // Show your progress indicator.
    }

    @Override
    public void onNext(String message) {
      // Hide your progress indicator and show the result.
    }
  }
);

buttonInput.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    inputLoader.restart(editInput.getText().toString());
  }
});

Tags

It is possible that you have multiple loaders for a given RxLoaderManager. In that case you must pass each one a unique tag (loaderManager.create(MY_TAG, observable, callback)). This is a string that identifies which callback is attached to which observable so it can be reattached on a configuration change.

You may notice the above examples do not have a tag. If none is provided, then then RxLoaderManager#DEFAULT is used.

Saving state

The Android OS might destroy and recreate your Activity sometimes. If you don't want to re-request data for your UI, you can save the result in the Activity's instance state.

This can be as easy as

loaderManager.create(observable, callback).save().start();

This assumes that the observable's value implements Parceable. If it doesn't, you can handle saving and restoring it yourself by passing in a SaveCallback.

loaderManager.create(observable, callback)
  .save(new SaveCallback<Result>() {
    @Override
    public void onSave(String tag, Result value, Bundle outBundle) {
      // Save the value in the bundle.
    }

    @Override
    public Result onRestore(String tag, Bundle savedState) {
      // Return the value from the bundle.
    }
  }).start();

Transient State

It may be the case that the result returned by your observable is transient and you don't want it to show any more after it's been handled (a Toast for example). In that case, you can call clear() on the loader to reset it so that it will no longer be delivered on configuration changes.

final RxLoader<Result> loader = loaderManager.create(
  asyncThatReturnsObservable(),
  new RxLoaderObserver<Result>() {
    @Override
    public void onStarted() {
      // Show your progress indicator.
    }

    @Override
    public void onNext(Result result) {
      // Hide your progress indicator and show the result.
    }

    @Override
    public void onError(Throwable error) {
        Toast.makeText(context, error.getMessage(), Toast.LENGTH_SHORT).show();
        loader.clear(); // onError() won't get called again when you rotate. 
    }
  }
).start(); // Make sure you call this to kick things off.

A note about usage

RxLoader does nothing to effect to thread in which the observable you passed in is run on. That means if you use Observable.create(...) you may find that your "background" action is run on the UI thread. Fixing this is easy, just use observable.subscribeOn(...) to run the observable on the given scheduler.

More Repositories

1

gradle-retrolambda

A gradle plugin for getting java lambda support in java 6, 7 and android
Java
5,315
star
2

binding-collection-adapter

Easy way to bind collections to listviews and recyclerviews with the new Android Data Binding framework
Java
1,911
star
3

kotlin-inject

Dependency injection lib for kotlin
Kotlin
1,165
star
4

JobSchedulerCompat

[Deprecated] A backport of Android Lollipop's JobScheduler to api 10+
Java
735
star
5

android-studio-unit-test-plugin

[Deprecated] Android Studio IDE support for Android gradle unit tests. Prepared for Robolectric.
Java
235
star
6

holdr

[Deprecated] Because typing findViewById() in Android is such a pain.
Java
208
star
7

redux

Redux ported to java/android (name tbd)
Java
192
star
8

android-retrolambda-lombok

A modified version of lombok ast that allows lint to run on java 8 sources without error.
Java
175
star
9

compose-collapsable

A generic collapsable implementation with dragging and nested scrolling support
Kotlin
91
star
10

compose-shown

Provides a callback for when a @Composable is shown to the user
Kotlin
65
star
11

injectedvmprovider

Small lib to use easily use Android's ViewModels with a depedency injection framework like dagger
Java
51
star
12

yield-layout

Combine layouts in Android, opposite of how <include/> works.
Java
50
star
13

gsonvalue

Compile-time generation of gson TypeAdapters to preserve class encapsulation
Java
42
star
14

simplefragment

A fragment-like abstraction for Android that is easier to use and understand
Java
41
star
15

streamqflite

flutter reactive stream wrapper around sqflite inspired by sqlbrite
Dart
40
star
16

android-shard

'Fragments' with a simpler api built on top of the android architecture components
Java
29
star
17

studio-splash

An archive of all the Android Studio splash images
Kotlin
26
star
18

timesync

Android library for periodicly syncing data from server.
Java
25
star
19

android-quiznos

Sad about the boring Android 10 naming? This lib give you some options to spice things up.
Java
23
star
20

PokeMVVM

A playground for MVVM style architecture on Android
Java
17
star
21

parsnip

A modern XML library for Android and Java
Java
15
star
22

kotlin-inject-samples

Verious samples using kotlin-inject
Kotlin
15
star
23

android-biometrics-compat-issue

A sample implementation of the androidx biometric compat lib with all the workarounds needed for a production app
Kotlin
15
star
24

loadie

Android Loaders for the rest of us
Java
14
star
25

retain-state

A dead simple way to retain some state thought configuration changes on Android
Java
12
star
26

spanalot

A simple utility for creating and modifying spannables in Android
Java
11
star
27

wiiafl

Wrap it in a FrameLayout
Kotlin
10
star
28

recyclerview-sample

An example of how to use Android L's new RecyclerView with a custom ItemAnimator
Java
10
star
29

voice-changer

Playing around with real-time audio processing on andriod with rust
Kotlin
9
star
30

fragstack

A better android fragment backstack
Kotlin
9
star
31

android-apngrs

Android bindings to image-rs for APNG support.
Kotlin
8
star
32

NyandroidRestorer

Restore our favorite pop-tart-rainbow friend in Android Studio.
Java
7
star
33

android-safe-rxjava-usage

An example of safely using rxjava on Android
Java
7
star
34

nav

A simple declarative Android compose navigator
Kotlin
7
star
35

jackport

Backporting java 8 apis to older versions of android using the jack plugin system.
Java
7
star
36

kotlin-fragment-dsl

A nice kotlin dsl for dealing with the fragment backstack.
Kotlin
7
star
37

sres

Super-Duper Android Layout Preprocessor
Java
6
star
38

assertk

This project has moved to https://github.com/willowtreeapps/assertk
Kotlin
6
star
39

auto-value-lens

AutoValue extension to create lenses for AutoValue properties
Kotlin
5
star
40

flutter_study

Flashcard app written in flutter
Dart
5
star
41

fasax

The fastest way to unmarshall XML to Java on Android
Java
5
star
42

value-processor

Helper for creating annotation processors that create/read value objects.
Kotlin
5
star
43

sparkle

A compiler for FiM++ written in rust
Rust
5
star
44

webpush-fcm-relay

Relays WebPush messages to Firebase Cloud Messaging
Kotlin
5
star
45

typedbundle

Typesafe key-value parinings for Android Bundles.
Java
4
star
46

animated-spans

Playing arround with animating spans in an EditText
Java
4
star
47

silent-support

Backport new android api calls to support lib versions.
Java
4
star
48

FitTextView

Android TextView that scales text to fit area
Java
3
star
49

webpush-encryption

A lightweight webpush encryption/decryption library
Kotlin
3
star
50

kotlin-ir-plugin-example

Playinig around with kotlin ir plugin support added for compose
Kotlin
3
star
51

ipromise

small proimse/future library for java and Android
Java
3
star
52

quickreturn-listview

A quickreturn for a listview in android
Java
3
star
53

yesdata

Errorprone check to verify you have implemented data classes correctly.
Java
3
star
54

domain-mapper

Generates code to map from one domain object to another
Kotlin
3
star
55

kotlin-inject-android

Android extensions to kotlin-inject
Kotlin
2
star
56

named-semaphore

Safe wrapper of libc's named semaphores
Rust
2
star
57

viewpager2stateissue

Kotlin
2
star
58

vimrc

Vim Script
2
star
59

google-actions-wolfram

Query Wolfram Alpha using Google Actions api
JavaScript
2
star
60

gradle-central-release-publishing

An opinionated gradle plugin to manage publishing to maven central
Kotlin
2
star
61

autodata

An extensable alternative to AutoValue.
Java
2
star
62

ponysay-rust

A barebones port of ponysay to rust.
Rust
2
star
63

.emacs.d

My emacs config
JavaScript
2
star
64

RxJavaLeak

A sample project showing a memory leak in RxJava
Java
2
star
65

res

Commandline res manager for android
Rust
2
star
66

fragment-recreator

A utility to handle fragment view-recreation when used in an Activity that handles configuration changes
Kotlin
2
star
67

crequire

A simple way to require c code in ruby using SWIG
Ruby
2
star
68

adp

Android Device Pool
Rust
1
star
69

fragment-view-issue

Kotlin
1
star
70

recyclerview-issue2

Kotlin
1
star
71

android-gradle-jack-plugin

Fork of the android gradle plugin that supports jack plugins
Java
1
star
72

blog

HTML
1
star
73

paging-issue

Kotlin
1
star
74

instance_state

[WIP] Flutter plugin to save/restore instance state on Android
Dart
1
star
75

app-test

Kotlin
1
star
76

android-scroll-to-position-test

Testing how often onBindViewHolder is called when using scrollToPosition() on recyclerview
Java
1
star
77

wordlists

A web application to create and use large lists of words
Ruby
1
star
78

studio-dep-sub-issue

Build failure when using a dependencySubstitution
Java
1
star
79

kotlin-mpp-ui-test

Expirmental cross-platform ui tests with kotlin multiplatform
Swift
1
star
80

placeholder-edittext

Java
1
star
81

prime-multiples

Code for MPMP 19 in rust https://www.think-maths.co.uk/19challenge
Rust
1
star
82

docker-compose-test

A helper to run integration tests with docker-compose
Rust
1
star
83

recyclerview-predraw-issue

Issue with recyclerview animations and predraw listeners
Java
1
star
84

paging-compose-refresh-issue

Kotlin
1
star
85

compose-dialog-window-insets-issue

Kotlin
1
star