UI阻塞发生在Android中,尽管RxJava [英] UI blocking occurs in Android despite RxJava
问题描述
我使用RxJava移动网络接入到Android的一个单独的线程,但我的UI还是块。
I am using RxJava to move network access to a separate thread in Android, but my UI still blocks.
我没有使用了错误的观察到的,如下所示:的Android RxJava,非阻塞
I am not using the wrong observable as shown here: Android RxJava, Non Blocking?
在codepoints [A],[B]和[C]在下面code的传递顺序[A] - > [C] - > [B]所以目前螺纹加工精和RxJava调用[C],一旦有了结果。这是好的。
The codepoints [A], [B] and [C] in below code are passed in the order [A] -> [C] -> [B] so the current thread is processed fine and RxJava calls [C] once it had a result. This is fine.
此外,阻塞好得多相比,这样做的UI线程上的网络电话,但我仍然有轻微阻塞。电话就被打出后的UI保持流畅,但是如果服务器未在几毫秒内做出反应,它会阻止。
Also, blocking is much better compared to doing the network call on the UI thread, but I still have minor blocking. The UI stays fluent after the call is made, but if the server does not respond in a matter of milliseconds, it blocks.
private search; // search is an instance variable in the same class
// [A]
Observable.just(search.find("something")) // search.find calls the REST endpoint
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Search>() {
@Override public void call(Search search) {
// further processing // [B]
}
}, new Action1<Throwable>() {
@Override public void call(Throwable throwable) {
// error handler
}
});
// [C]
这可能是一个问题,搜索是在可观察使用它的同一个类的实例变量,但终端呼叫从一个单独的库进行?它不应该的问题,对吧?
Could it be a problem that search is an instance variable in the same class where the Observable uses it, but the endpoint call is performed from a separate library? It shouldn't matter, right?
我在做什么不好,我不应该做?
Am I doing anything bad that I shouldn't be doing?
-
查找看起来是这样的(除去异常处理简洁):
Find looks like this (removed exception handling for brevity):
public Search find(String searchtext) {
setSearchtext(searchtext);
SearchEndpoint.find(Session.getUser().getId(), searchtext);
return this;
}
SearchEndpoint是这样的:
SearchEndpoint like this:
public static Search find(final Long userId, final String searchtext) throws IOException {
return ApiService.api().searches().find(userId).setFind(searchtext).execute();
}
和将调用生成的谷歌云终端库。
and makes a call to the generated Google cloud endpoint library.
推荐答案
试试这个:
Observable.create(new Observable.OnSubscribe<Search>() {
@Override
// method signature is from memory - I hope I am correct...
public void call(Subscriber<? super Search> subscriber) {
try {
Search search = search.find("something");
subscriber.onNext(search);
subscriber.onCompleted();
} catch (SomeException e) {
subscriber.onError(e);
}
}
})
// and then continue with your .subscribeOn(...)
要澄清一下,也许这让你的code中的问题更加明显:
To clarify, maybe this makes the problem with your code more obvious:
Observable.just(search.find("something"))
显然等同于
Search search = search.find("something");
Observable.just(search)
和这使得它很明显,search.find执行之前我们曾经交出了控制权交给rxjava,它是在执行任何线程的是当前 - 那么可观察到的从pre计算的价值建设和值的传递发生在另一个线程,但它不能帮助你多少...
And this makes it obvious that search.find is executed before we ever hand the control over to rxjava and it is executed on whatever thread you are currently on - then the construction of an Observable from the pre-computed value and the delivery of the value happen on another thread but that does not help you much...
这篇关于UI阻塞发生在Android中,尽管RxJava的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!