bluelinelabs / bluelinelabs/Conductor
Cannot bind to Controller lifecycle when outside of it using targetController and AutoDispose
- Dominant language
- Java
- Stars
- 3.9k
- Forks
- 338
- PR merge metrics
- No merged PRs in 30d
Description
When I'm using TargetController, Rx and AutoDisposable app fails with `io.reactivex.exceptions.OnErrorNotImplementedException: Cannot bind to Controller lifecycle when outside of it.`
Steps to reproduce:
* Open `TargetDisplayController.class` and add
```
private final LifecycleScopeProvider scopeProvider = ControllerScopeProvider.from(this);
```
* replace `onTitlePicked` with
```
@Override
public void onTitlePicked(String option) {
Observable.just(option)
.observeOn(AndroidSchedulers.mainThread())
.to(new ObservableScoper(scopeProvider))
.subscribe(new Consumer() {
@Override
public void accept(final String s) throws Exception {
selectedText = s;
setTextView();
}
});
}
```
* Pick a title and wait for logs:
```
W: io.reactivex.exceptions.OnErrorNotImplementedException: Cannot bind to Controller lifecycle when outside of it.
W: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
W: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
W: at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74)
W: at com.uber.autodispose.AutoDisposingObserverImpl.onError(AutoDisposingObserverImpl.java:98)
W: at com.uber.autodispose.AutoDisposingObserverImpl$2.accept(AutoDisposingObserverImpl.java:53)
W: at com.uber.autodispose.AutoDisposingObserverImpl$2.accept(AutoDisposingObserverImpl.java:51)
W: at io.reactivex.internal.operators.maybe.MaybeCallbackObserver.onError(MaybeCallbackObserver.java:81)
W: at io.reactivex.internal.operators.maybe.MaybeDoOnEvent$DoOnEventMaybeObserver.onError(MaybeDoOnEvent.java:100)
W: at io.reactivex.internal.operators.maybe.MaybeError.subscribeActual(MaybeError.java:35)
W: at io.reactivex.Maybe.subscribe(Maybe.java:3725)
W: at io.reactivex.internal.operators.maybe.MaybeDefer.subscribeActual(MaybeDefer.java:48)
W: at io.reactivex.Maybe.subscribe(Maybe.java:3725)
W: at io.reactivex.internal.operators.maybe.MaybeDoOnEvent.subscribeActual(MaybeDoOnEvent.java:39)
W: at io.reactivex.Maybe.subscribe(Maybe.java:3725)
W: at io.reactivex.Maybe.subscribeWith(Maybe.java:3791)
W: at io.reactivex.Maybe.subscribe(Maybe.java:3712)
W: at io.reactivex.Maybe.subscribe(Maybe.java:3678)
W: at com.uber.autodispose.AutoDisposingObserverImpl.onSubscribe(AutoDisposingObserverImpl.java:47)
W: at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.onSubscribe(ObservableObserveOn.java:92)
W: at io.reactivex.internal.operators.observable.ObservableJust.subscribeActual(ObservableJust.java:34)
W: at io.reactivex.Observable.subscribe(Observable.java:10842)
W: at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:45)
W: at io.reactivex.Observable.subscribe(Observable.java:10842)
W: at com.uber.autodispose.ObservableScoper$AutoDisposeObservable.subscribeActual(ObservableScoper.java:111)
W: at io.reactivex.Observable.subscribe(Observable.java:10842)
W: at io.reactivex.Observable.subscribe(Observable.java:10828)
W: at io.reactivex.Observable.subscribe(Observable.java:10731)
W: at com.uber.autodispose.ObservableScoper$1.subscribe(ObservableScoper.java:69)
W: at com.bluelinelabs.conductor.demo.controllers.TargetDisplayController.onTitlePicked(TargetDisplayController.java:67)
W: at com.bluelinelabs.conductor.demo.controllers.TargetTitleEntryController.optionPicked(TargetTitleEntryController.java:52)
W: at com.bluelinelabs.conductor.demo.controllers.TargetTitleEntryController_ViewBinding$1.doClick(TargetTitleEntryController_ViewBinding.java:31)
W: at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
W: at android.view.View.performClick(View.java:6256)
W: at android.view.View$PerformClick.run(View.java:24697)
W: at android.os.Handler.handleCallback(Handler.java:789)
W: at android.os.Handler.dispatchMessage(Handler.java:98)
W: at android.os.Looper.loop(Looper.java:164)
W: at android.app.ActivityThread.main(ActivityThread.java:6541)
W: at java.lang.reflect.Method.invoke(Native Method)
W: Not supplying enough data to HAL, expected position 44375279 , only wrote 44375040
W: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
W: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
W: Caused by: com.uber.autodispose.OutsideLifecycleException: Cannot bind to Controller lifecycle when outside of it.
W: at com.bluelinelabs.conductor.autodispose.ControllerScopeProvider$1.apply(ControllerScopeProvider.java:30)
W: at com.bluelinelabs.conductor.autodispose.ControllerScopeProvider$1.apply(ControllerScopeProvider.java:15)
W: at com.uber.autodispose.ScopeUtil$3.call(ScopeUtil.java:89)
W: at com.uber.autodispose.ScopeUtil$3.call(ScopeUtil.java:74)
W: at io.reactivex.internal.operators.maybe.MaybeDefer.subscribeActual(MaybeDefer.java:41)
W: ... 30 more
W: Force finishing activity com.bluelinelabs.conductor.demo/.MainActivity
```
Is it desired behavior? Could you suggest workarounds?
Contributor guide
Research direction
Reproduce the example in TargetDisplayController by adding ControllerScopeProvider.from(this) and using ObservableScoper, then read ControllerScopeProvider.java and the stack trace around OutsideLifecycleException. Compare the controller lifecycle state when onTitlePicked runs with the scope requirements; done means the expected behavior and a supported workaround are documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, java
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100