以下是我的确切代码。请注意,在subscribe lambda函数中调用了foo(o)。这在Android中提供了严格的模式错误。现在我当然可以在这里分拆一个线程,但这是Rxjava的做事方式吗?我现在必须再考虑线程吗?想在这里知道我最好的选择。我怎么能这样做RxJava方式,以便代码的其他部分可以订阅将返回网络呼叫响应的新事件?基本上我通过异步响应将一种类型的事件MyObj转换为NetObj响应事件。
public static final PublishSubject<MyObj> myObjSubject = PublishSubject.create();
public static final Observable<MyObj> observable = myObjSubject.asObservable();
protected CompositeSubscription myCompositeSubs = new CompositeSubscription();
myCompositeSubs.add(
observable.subscribe((MyObj o) -> {
// `. Update UI with MyObject and
// 2. Kick off network call which will return JsonResponse type object which I would like to possibly process here and also publish to let others respond to it.
foo(o); // $$$$$ million dollar question what if I am kicking off something long running here?
}));
private void foo(MyObj o){
// long running request. How to kick off long running from here?
JsonRespons resp = RestAdapter.makeQuest(o.url);
// I want this JsonResponse object to be an even others can listen for. I don't want to just process it right here.
}
更新:只是为了澄清我想要做的是在类(Android Fragment)中监听数据事件MyObject。一旦我得到这个,我想做两件事,与MyObject同步更新UI,这是我想要消费的而不仅仅是转换。但我也想开始一个长期运行的请求。一个网络调用,它返回JsonObject响应。这可能会在它返回时处理相同的片段,或者我可能希望其他类能够监听此事件。所以我不是仅仅观察MyObject然后进行网络调用并获得响应。我需要做两个操作,一个同步另一个异步。
答案 0 :(得分:3)
这是使用像flatMap
这样的RxJava运算符的绝佳机会。如果您需要更多文档,请查看here,但flatMap
允许您获取一个类型的Observable(您的Observable<MyObj>
)并返回另一种类型的Observable(在这种情况下它可以如果您想知道您的长时间运行请求是否完成,请Observable<Void>
或Observable<Boolean>
。
看看这段代码:
Subscription sub = observable.flatMap((MyObj o) -> {
// this will be run on your subscribeOn thread -- in background
return Observable.just(foo(o));
}).subscribe(aVoid -> {
// we have completed both operations here, emissions will be
// on our observeOn() thread
});
您的foo(MyObj)
功能现在的结构为:
private Void foo(MyObj o) {
// long running stuff
return null;
}
返回类型Void
而非void
非常重要,这样我们才能使用flatMap
运算符并返回Observable<Void>
。
所有长时间运行的foo()
操作都将在您的subscribeOn()
线程上运行,同时还有您的初始observable,一旦操作完成,它将向您发出Void
项您subscribe()
主题上的observeOn()
(如果您想通知用户界面,这可以是Android中的主要主题)。
更新以允许在flatMap调用中使用UI:
注意:这假设第一个observable
已在后台主题定义subscribeOn()
而observeOn()
定义为AndroidSchedulers.mainThread()
Subscription sub = observable.flatMap((MyObj o) -> {
// << do stuff with MyObj to UI HERE >>
return Observable.defer(() -> Observable.just(foo(o)))
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}).subscribe(aVoid -> {
// foo() has completed, we're back on the UI thread
});
如果你想对JsonResponse做一些事情,你会改变foo()
函数来返回Void
而不是foo()
,那么你就可以使用Observable.create()
的结果在UI线程上。
更新2:将Observable.defer()
更改为image2 = Image.open('./Images/Cache/Cache.png')
finalimage = QtGui.QIcon()
finalimage.addPixmap(QtGui.QPixmap(image2), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.FinalImage.setIcon(finalimage)
self.FinalImage.setIconSize(QtCore.QSize(1300, 342))
以使其更清晰。