我正在阅读教程:
http://code.tutsplus.com/tutorials/getting-started-with-reactivex-on-android--cms-24387
特别是RxAndroid,但它与RxJava几乎相同。我不确定我是否完全理解这个概念。
下面我编写了一个方法,然后是一个示例用法。
我的问题是:这是实现我的函数的正确方法,以便我可以异步地在其他线程上运行它们吗?实际上,它们只会返回一个运行真实代码的已创建Observable,并处理错误和所有这些内容。
或者这是错的,那么我想知道正确的方法。
Observable<String> googleSomething(String text){
return Observable.create(new Observable(){
@Override
public void call(Subscriber<? super String> subscriber) {
try {
String data = fetchData(text); // some normal method
subscriber.onNext(data); // Emit the contents of the URL
subscriber.onCompleted(); // Nothing more to emit
} catch(Exception e) {
subscriber.onError(e); // In case there are network errors
}
}
});
}
googleSomething("hello world").subscribeOn(Schedulers.io()).observeOn(Schedulers.immediate()).subscribe(...)
还使用Schedulers.immediate()来执行当前线程上的订户代码?它说“创建并返回一个在当前线程上立即执行工作的调度程序。”在javadoc,但我不确定。
答案 0 :(得分:7)
除非您更有经验并需要自定义运算符或想要桥接基于旧版addListener / removeListener的API,否则不应以create
开头。 StackOverflow上有几个问题使用create
并且是麻烦的来源。
我更喜欢fromCallable
,它让您生成单个值或抛出异常,因此不需要那些冗长的defer
+ just
来源。
Schedulers.immediate()
立即在调用者的线程上执行其任务,该线程是示例中的io()线程,而不是主线程。目前,不支持将计算移回 Java 主线程,因为它需要阻止蹦床,并且通常是一个坏主意。
答案 1 :(得分:2)
你几乎不应该使用create()
,尤其不是初学者。有更简单的方法来创建可观察对象,create()
很难正确实现。
大多数情况下,您可以使用create()
轻松绕过defer()
。例如,在这种情况下你会做:
Observable<String> googleSomething(String text) {
return Observable.defer(new Func0<Observable<String>>() {
@Override
public Observable<String> call() {
try {
return Observable.just(fetchData(text));
} catch (IOException e) {
return Observable.error(e);
}
}
});
}
如果您没有使用已检查的异常,那么您甚至可以摆脱try-catch。 RxJava会自动将任何RuntimeException
转发给订阅者的onError()
部分。
答案 2 :(得分:1)
您可以通过Observable.create(new OnSubscribe {})方法创建Observable:
Schedulers.immediate()将在它已经存在的线程上保持Observable处理 - 所以在你的情况下它将是Schedulers.io线程之一
答案 3 :(得分:1)
您的代码对我来说很好。如果你不确定是否在另一个线程上运行。您可以在致电.subscribe()
后立即打印一些内容并查看输出的顺序。
googleSomething("hello world").subscribeOn(Schedulers.io()).observeOn(Schedulers.immediate()).subscribe(...)
System.out.println("This should be printed first");
尝试在fetchData()
内模拟长时间运行的操作,然后立即打印其他内容。因为.subscribe()是非阻塞的,所以应该首先打印#34;事实上,将首先打印。
或者,您可以使用。
打印当前线程Thread.currentThread().getName()
在您的observable内外使用它,输出应该不同。