RxJava2结合Realm出现实例已关闭异常,求助排查问题根源
Hey, I’ve dealt with this exact headache when pairing Realm and RxJava—let’s walk through the most likely culprits and how to fix them, even though RealmObservableFactory is supposed to handle instance creation per subscription.
1. You’re manually closing a shared Realm instance
This is the most common cause. If you grab a Realm instance, pass it into an Rx stream, then close it before the stream finishes processing, you’ll hit this error every time. For example:
Realm realm = Realm.getDefaultInstance(); // Pass this realm into your observable myDataStream .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { // Do something with realm }); realm.close(); // Oops—you closed the instance before the stream is done!
Fix it by:
- Letting
RealmObservableFactoryhandle instance creation/recycling entirely—don’t manually pass Realm instances into Rx streams unless you’re using a lifecycle-bound wrapper. - If you must manually create an instance, use RxJava’s
usingoperator to tie the Realm instance’s lifecycle to the stream:
Observable.using( () -> Realm.getDefaultInstance(), // Create the instance realm -> realm.where(YourModel.class).findAllAsync().asObservable(), // Use it in the stream Realm::close // Close it when the stream completes/errors ) .subscribe(...);
2. Cross-thread Realm instance access
Realm instances are thread-locked—if you switch threads in your Rx stream (with subscribeOn/observeOn) and reuse a Realm instance from another thread, you’ll run into issues when the original thread’s instance gets closed.
Fix it by:
- Always fetch a new Realm instance on the thread where you’re using it. Realm’s Rx extensions usually handle this automatically, but if you’re doing custom thread switching, make sure you call
Realm.getDefaultInstance()on the target thread. - Never pass a Realm instance across threads—let each stream stage create its own instance if needed.
3. Hidden reference count issues
Realm uses reference counting to manage instances, and while RealmObservableFactory increments counts on subscribe and decrements on unsubscribe, edge cases can break this:
- Multiple subscriptions to the same stream where one unsubscribe triggers an early close.
- Delayed operators (like
delayordebounce) that let the instance be closed elsewhere while waiting.
Fix it by: - Avoid reusing Realm instance references across different subscriptions—each subscription should get its own fresh instance.
- If using operators like
retryorrepeat, ensure each retry cycle creates a new Realm instance instead of reusing the old one. - Double-check any custom logic or third-party libraries that might be messing with Realm’s reference counts (like closing instances outside of Rx’s lifecycle).
4. Lifecycle cleanup gaps
If your Rx stream is tied to a UI component (Activity/Fragment) and you don’t properly unsubscribe when the component is destroyed, the stream might keep running after the component’s associated Realm instance has been closed.
Fix it by:
- Use a
CompositeDisposableto track all your subscriptions, and calldispose()in your component’sonDestroymethod. - Consider using a lifecycle-binding library to automatically terminate streams when the UI component is destroyed—this eliminates the chance of dangling Realm references.
内容的提问来源于stack exchange,提问作者elnino

