Last active
August 21, 2020 22:25
-
-
Save magillus/927f863987575021dc78249bd8064423 to your computer and use it in GitHub Desktop.
RxJava2.0 Broadcast Receiver for getting intent broadcasts as Observable<Intent>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IntentFilter intentFilter = new IntentFilter(); | |
intentFilter.addAction("com.example.mat.ACTION_START"); | |
intentFilter.addAction("com.example.mat.ACTION_STOP"); | |
Disposable disposable = RxBroadcastReceiver.create(this, intentFilter) | |
.share() // optional if you want do not want multiply broadcast receivers created | |
.map(SOMECLASS::someStaticMethod) // example mapping method for parsing data from Intent | |
.subscribe(data -> {......}); | |
disposable.dispose(); // that or use CompositeDisposable | |
SOMECLASS: | |
public static Data someStaticMethod(Intent intent) { | |
// fetch data from intent EXTRAs | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* RxJava based broadcast reciever that registers its local BroadcastReceiver until end of subscription. | |
* Listens for update and passes Intent to the Stream (Subscriber). | |
* | |
* Copyright 2016 Mateusz Perlak - http://www.apache.org/licenses/LICENSE-2.0 | |
* Created on 11/18/16. | |
*/ | |
public class RxBroadcastReceiver implements ObservableOnSubscribe<Intent> { | |
protected final WeakReference<Context> contextWeakReference; | |
private IntentFilter intentFilter; | |
/** | |
* Creates Observable with intent filter for Broadcast receiver. | |
* | |
* @param context | |
* @param intentFilter | |
* @return | |
*/ | |
public static Observable<Intent> create(Context context, IntentFilter intentFilter) { | |
return Observable.defer(() -> Observable.create(new RxBroadcastReceiver(context, intentFilter)) | |
.subscribeOn(Schedulers.io()) | |
); | |
} | |
/** | |
* @param context | |
* @param intentFilter | |
*/ | |
private RxBroadcastReceiver(Context context, IntentFilter intentFilter) { | |
contextWeakReference = new WeakReference<Context>(context.getApplicationContext()); | |
this.intentFilter = intentFilter; | |
} | |
@Override | |
public void subscribe(ObservableEmitter<Intent> emitter) throws Exception { | |
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
emitter.onNext(intent); | |
} | |
}; | |
emitter.setDisposable(Disposables.fromRunnable(() -> { // thank you Jake W. | |
if (contextWeakReference != null && contextWeakReference.get() != null) { | |
contextWeakReference.get().unregisterReceiver(broadcastReceiver); | |
} | |
})); | |
if (contextWeakReference != null && contextWeakReference.get() != null) { | |
contextWeakReference.get().registerReceiver(broadcastReceiver, intentFilter); | |
} | |
} | |
} |
Hello, I'm curious, isn't better to use just this one:
@NonNull
public static Observable<Intent> create(@NonNull final Context context, @NonNull final IntentFilter intentFilter) {
final Context appContext = context.getApplicationContext();
return Observable.create(emitter -> {
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
emitter.onNext(intent);
}
};
appContext.registerReceiver(receiver, intentFilter);
emitter.setCancellable(() -> appContext.unregisterReceiver(receiver));
});
}
Some notes here: we don't need WeakReference for Application Context, because dynamic receiver exists only in the scope of current Application instance (it is a Singleton for Android app process).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oh ok got it,
Observable.defer
will make sure a newBroadcastReceiver
is created every time?What if we just set emitter to
null
and setisDisposed
toemitter == null
and reuse theBroadcastReceiver
? Which would be a better way?