Activity 中的(替代)或(正确使用)AndroidObservables
(Alternative to) or (proper use of ) AndroidObservables in Activity
我一直在使用 AndroidObservable
s 进行需要在 UI 线程之外发生的操作。我现在发现自己处于这种情况:我需要在主线程外做一个操作,然后根据结果更改 UI。我的尝试是这样的:
subscription = AndroidObservable.bindActivity(this, Observable.just(null))
.observeOn(Schedulers.io())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
if (doCheckThatMustBeOffMainThread()) {
doSomethingWithTheUI();
}
}
});
这是有问题的,因为我现在正在与主线程之外的 UI 进行交互。
我使用 AndroidObservable
s 的部分原因是我知道(认为?)我可以通过取消订阅 onDestroy()
来避免内存泄漏,但考虑到 AndroidObservable
的这种使用看起来是多么人为(创建一个发出 null 的 observable……)并且我无法在主线程上与 UI 交互,这让我认为可能有更合适的使用 AndroidObservable
s 的方法——或者另一种方法是也可以防止内存泄漏。这些可能是什么?
您需要将检查移动到它自己的 Observable。这样你就可以控制它运行的调度程序。
Observable<Boolean> doCheckObservable =
Observable
.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
// Runs on the io thread when subscribed to.
// Do check that returns true or false.
subscriber.onNext(doCheckThatMustBeOffMainThread());
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io());
Subscription subscription =
AndroidObservable
.bindActivity(this, doCheckObservable)
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean doThatCheckPassed) {
if (doThatCheckPassed) {
// bindActivity() makes this run on the main thread.
doSomethingWithTheUI();
}
}
});
// NOTE: This is now AppObservable in the latest RxAndroid release.
AndroidObservable.bindActivity(this, Observable.defer(
new Func0<Observable<Void>>() {
@Override
public Observable<Void> call() {
return doCheckThatMustBeOffMainThread() ?
Observable.just(null) : Observable.empty();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Void>() {
@Override
public void call(Void unused) {
doSomethingWithTheUi();
}
}));
这样你仍然通过一个可观察对象推送 null,但这次它只是被用作一个信号,并且工作发生在你需要它的地方:在 io land 中签出,以及在UI 个线程。
我一直在使用 AndroidObservable
s 进行需要在 UI 线程之外发生的操作。我现在发现自己处于这种情况:我需要在主线程外做一个操作,然后根据结果更改 UI。我的尝试是这样的:
subscription = AndroidObservable.bindActivity(this, Observable.just(null))
.observeOn(Schedulers.io())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
if (doCheckThatMustBeOffMainThread()) {
doSomethingWithTheUI();
}
}
});
这是有问题的,因为我现在正在与主线程之外的 UI 进行交互。
我使用 AndroidObservable
s 的部分原因是我知道(认为?)我可以通过取消订阅 onDestroy()
来避免内存泄漏,但考虑到 AndroidObservable
的这种使用看起来是多么人为(创建一个发出 null 的 observable……)并且我无法在主线程上与 UI 交互,这让我认为可能有更合适的使用 AndroidObservable
s 的方法——或者另一种方法是也可以防止内存泄漏。这些可能是什么?
您需要将检查移动到它自己的 Observable。这样你就可以控制它运行的调度程序。
Observable<Boolean> doCheckObservable =
Observable
.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
// Runs on the io thread when subscribed to.
// Do check that returns true or false.
subscriber.onNext(doCheckThatMustBeOffMainThread());
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io());
Subscription subscription =
AndroidObservable
.bindActivity(this, doCheckObservable)
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean doThatCheckPassed) {
if (doThatCheckPassed) {
// bindActivity() makes this run on the main thread.
doSomethingWithTheUI();
}
}
});
// NOTE: This is now AppObservable in the latest RxAndroid release.
AndroidObservable.bindActivity(this, Observable.defer(
new Func0<Observable<Void>>() {
@Override
public Observable<Void> call() {
return doCheckThatMustBeOffMainThread() ?
Observable.just(null) : Observable.empty();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Void>() {
@Override
public void call(Void unused) {
doSomethingWithTheUi();
}
}));
这样你仍然通过一个可观察对象推送 null,但这次它只是被用作一个信号,并且工作发生在你需要它的地方:在 io land 中签出,以及在UI 个线程。