question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ignore(don't save reference to) disposable returning after subscription. RxJava2

See original GitHub issue

Hello, and thx for your great work. I’m Android developer and I faced with some situation. I use Observable.create(…) to wrap listeners and move into reactive-world:

  Observable.create(emitter -> {
            SharedPreferences sharedPreferences = getSharedPreferences();
            SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, key) -> emitter.onNext(sharedPreferences.getBoolean("Some key", false));
            sharedPreferences.registerOnSharedPreferenceChangeListener(listener);
            emitter.setCancellable(() -> sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener));
        });

The problem is, this listener is stroring as WeakReference at SharedPreferences. In that case, only Disposable, returning after Observable.subscribe(…) method will save strong-reference to this listener.

Sometimes it does not neccessary for me to persist that Disposable, because i won’t dispose() my subscription. But in this case( don’t store reference to Disposable), my listener will be cleared by GC and my Observable stops emit items.

My question: Whether it is valid to not store Disposable, returning after subscribe(…) or not in common case. Or my code is wrong and I need to create some proxy-class, that will store strong-references in this case

Thx!

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:16 (9 by maintainers)

github_iconTop GitHub Comments

3reactions
einmalfelcommented, Aug 13, 2017

@akarnokd Nice solution! in our project we decided to go for SharedPrefs decorator that stores strong refs

2reactions
akarnokdcommented, Aug 10, 2017

Is registerOnSharedPreferenceChangeListener RxJava ? Let’s see a simplified example:

WeakReference<Integer> wr = new WeakReference<>(123456789);

Observable<Integer> obs = Observable.fromCallable(() -> wr.get());

System.gc();
Thread.sleep(200);

obs.test()
  .assertFailure(NullPointerException.class);

Unsurprisingly, RxJava failed to keep 123456789 alive.

RxJava can’t change such weak sources into strong ones and also can’t make you hold strong references to its own components.

Your case has nothing to do with RxJava. I assume the weak reference property of registerOnSharedPreferenceChangeListener was there all along and when you manually registered a listener, you kept a strong reference to the listener somewhere until it could be released. Now RxJava is taking the place of the listener thus you have to keep a strong reference of the observer or disposable you use/get back to prevent losing the listener. (This is no contradiction to my answer to @einmalfel question as he didn’t specify what sources he meant and my answer assumed standard RxJava sources that don’t have any weak references anywhere near them.)

Read more comments on GitHub >

github_iconTop Results From Across the Web

The result of subscribe is not used - Stack Overflow
The IDE does not know what potential effects your subscription can have when it's not disposed, so it treats it as potentially unsafe....
Read more >
RxJava2 UndeliverableException - ProAndroidDev
Today I started to got an error from Firebase Testlab due to UndeliverableException like below io.reactivex.exceptions.
Read more >
RxJava1 -> RxJava2 Upgrade Notes/Tips | by Ken Yee | Medium
This is a list of issues encountered/solved when upgrading a very large app (172 files that used RxJava) from RxJava 1.x to RxJava...
Read more >
Using RxJava 2 - Tutorial - Vogella.com
The Single class and other observable classes offer different subscribe methods, which return a Disposable object.
Read more >
Disposables Can Cause Memory Leaks - Zac Sweers
Simple, right? This is a classic pattern for avoiding memory leaks in RxJava code: keep the returned Disposable and dispose/clear it in the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found