Skip to content

Instantly share code, notes, and snippets.

@MariusBudin-zz
Created May 28, 2015 14:24
Show Gist options
  • Save MariusBudin-zz/21a58b8c2f207fa5e29d to your computer and use it in GitHub Desktop.
Save MariusBudin-zz/21a58b8c2f207fa5e29d to your computer and use it in GitHub Desktop.
A sample of how to perform post delayed calls using rxJava/rxAndroid avoiding the need to store an instance of a handler and cancel it in the onDestroy for each `postDelayed` call to avoid memory leaks
package com.ics.rxsamples
import android.app.Fragment;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.subjects.PublishSubject;
/**
* Created by marius on 28/5/15.
*
* @music Gramatik - Just Jammin'
*/
public abstract class BaseFragment extends Fragment {
private final PublishSubject<Void> destroyedSubject = PublishSubject.create();
/**
* An observable sending a next when the Fragment has been destroyed
*
* Example: use it with a takeUntil on your observable to ensure it's not going to leak
*/
public Observable<Void> destroyed() { return destroyedSubject.asObservable(); }
@Override
public void onDestroyView() {
super.onDestroyView();
destroyedSubject.onNext(null);
}
/**
* Performs an action after a certain delay
*
* Example: doAfterDelay(1, TimeUnit.SECONDS, ignored-> doSomething());
*/
public Subscription doAfterDelay(int time, TimeUnit timeUnit, Action1<Long> action) {
return delayObservable(time, timeUnit)
.subscribe(action);
}
/**
* Performs an action after a certain delay if the filter condition is met
*
* Example: doAfterDelay(1, TimeUnit.SECONDS,
* ignored-> stuff != null,
* ignored-> doSomething());
*/
public Subscription doAfterDelay(int time, TimeUnit timeUnit, Func1<Long, Boolean> filter, Action1<Long> action) {
return delayObservable(time, timeUnit)
.filter(filter)
.subscribe(action);
}
/**
* Performs an action after a certain delay in milliseconds
*
* Example: doAfterDelay(500, ignored-> doSomething());
*/
public Subscription doAfterDelay(int time, Action1<Long> action) {
return doAfterDelay(time, TimeUnit.MILLISECONDS, action);
}
/**
* Performs an action after a certain delay in milliseconds if the filter condition is met
*
* Example: doAfterDelay(1,
* ignored-> stuff != null,
* ignored-> doSomething());
*/
public Subscription doAfterDelay(int time, Func1<Long, Boolean> filter, Action1<Long> action) {
return doAfterDelay(time, TimeUnit.MILLISECONDS, filter, action);
}
private Observable<Long> delayObservable(int time, TimeUnit timeUnit) {
return Observable
.interval(time, timeUnit)
.observeOn(AndroidSchedulers.mainThread())
.first()
.takeUntil(destroyed());
}
}
@vickychijwani
Copy link

Love the use of takeUntil with PublishSubject, thanks for sharing! I'm still wrapping my head around RxJava basics.

@vickychijwani
Copy link

I believe the delayObservable code can be simplified slightly by using timer instead of interval, yes?

private Observable<Long> delayObservable(int time, TimeUnit timeUnit) {
    return Observable
            .timer(time, timeUnit)
            .observeOn(AndroidSchedulers.mainThread())
            .takeUntil(destroyed());
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment