我在Android上学习RxJava。我想在网络上使用它,所以我不能在主线程上做东西。
我有以下代码:
final String RXTAG = "Rx";
Log.d(RXTAG, "Starting Rx experiment");
final FutureTask<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws InterruptedException {
Log.d(RXTAG, "Callable called on thread " + Thread.currentThread().getName());
Utils.assertNotUIThread();
Thread.sleep(TimeUnit.SECONDS.toMillis(1)); // Simulates network latency
return "hello";
}
});
Observable.from(future, Schedulers.io()).timeout(5, TimeUnit.SECONDS).subscribe(
new Action1<String>() {
@Override
public void call(final String s) {
Log.d(RXTAG, "Next " + s);
}
},
new Action1<Throwable>() {
@Override
public void call(final Throwable throwable) {
Log.w(RXTAG, throwable);
}
},
new Action0() {
@Override
public void call() {
Log.d(RXTAG, "Completed");
}
}
);
但它在5个secunds之后以TimeoutException
结束,并且从未显示 Callable称为日志。什么错,以及如何让它发挥作用?
答案 0 :(得分:2)
尝试在订阅前添加以下代码。
.doOnSubscribe(disposable -> future.run())
.subscribeOn(Schedulers.io())
Rxjava2代码:
Observable.fromFuture(future, Schedulers.io())
.doOnSubscribe(disposable -> future.run())
.subscribeOn(Schedulers.io())
.subscribe(someConsumer()).
运行良好。
答案 1 :(得分:0)
您必须自己运行Future
。但不幸的是,它导致在主线程上运行Callable
,或者您必须使用Executor
。
相反,我提出以下解决方案:
// Extract Callable from FutureTask
Single.fromCallable(callable).timeout(5, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).subscribe(
new Action1<String>() {
@Override
public void call(final String s) {
Log.d(RXTAG, "Success " + s);
}
},
new Action1<Throwable>() {
@Override
public void call(final Throwable throwable) {
Log.w(RXTAG, throwable);
}
}
);
现在它按预期工作:
07-29 13:41:26.516 D/Rx: Starting Rx experiment
07-29 13:41:26.547 D/Rx: Callable called on thread RxIoScheduler-2
07-29 13:41:27.550 D/Rx: Success hello