Skip to content

[RFC] Improve support for auto-unsubscribing observables and newer language/API levels #12

Closed
@mttkay

Description

@mttkay

Currently, using Observables in Android components that have access to Context (or are themselves) requires one to carefully think about detaching from these sequences as part of the component life-cycle, since otherwise a closure the sequence holds a (strong) reference to might leak the current context until the time the sequence finishes and releases all subscribers.

A good example are configuration changes, where Android first destroys, then recreates an Activity, but observables might still be holding on to a subscriber created within the scope of that Activity. Even with retained fragments that detach from their host activity, it's easy enough to leak the attached context indirectly by holding on to a view first created through that context (every view in Android has a strong reference to the Activity context it was first created in.)

This ticket aims to find solutions to improve this situation, potentially by leveraging newer Android API levels where available, and/or add first class support for newer Java language levels (Java 8/Retrolambda)

Some suggestions that have been made already follow.

Android 14+ APIs

One option would be to make use of Activity life cycle callbacks:
http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html

This might allows us to unsubscribe once Android is about to destroy an activity.

Java 8 lambdas and Retrolambda

Part of the problem is that every "lambda" in Java 7 or below is an anonymous inner class that will hold a strong reference to the outer class, even if it's a pure function that does not access state outside the lambda. Java 8 + Retrolambda could help here, since pure functions will be materialized as static methods that hold no reference back to their owner.

http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html
https://github.com/orfjackal/retrolambda

Weak subscribers

We've taken several stabs at this and always dismissed the solution. The idea was to use WeakReferences to bind subscribers and lambdas. The problem with his approach is that it doesn't work with lambdas, since the only incoming reference would be weak, and they are eligible for GC the instant they're created. There might still be other ways to achieve this, however, I'll leave it open for discussion.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions