Android 链接改造服务,带RxJava支持

Android 链接改造服务,带RxJava支持,android,square,retrofit,netflix,rx-java,Android,Square,Retrofit,Netflix,Rx Java,我在使用改型的RxJava支持链接观测值时遇到了问题。我可能误解了如何使用它,否则它可能是改装中的一个bug。希望这里有人能帮我理解发生了什么编辑:我正在使用MockRestAdapter来处理这些响应-这可能与RxSupport实现略有不同有关 这是一个伪造的银行应用程序。它正在尝试进行传输,传输完成后,它应该执行帐户请求以更新帐户值。这基本上只是我尝试平面地图的一个借口。不幸的是,以下代码不起作用,没有订户收到通知: 案例1:链接两个改装产生的观测值 传输服务(注意:返回可观察到的改装):

我在使用改型的RxJava支持链接观测值时遇到了问题。我可能误解了如何使用它,否则它可能是改装中的一个bug。希望这里有人能帮我理解发生了什么编辑:我正在使用MockRestAdapter来处理这些响应-这可能与RxSupport实现略有不同有关

这是一个伪造的银行应用程序。它正在尝试进行传输,传输完成后,它应该执行帐户请求以更新帐户值。这基本上只是我尝试平面地图的一个借口。不幸的是,以下代码不起作用,没有订户收到通知:

案例1:链接两个改装产生的观测值

传输服务(注意:返回可观察到的改装):

@FormUrlEncoded@POST(“/user/transactions/”)
公共可观察传输(@Field(“session_id”)字符串sessionId,
@字段(“来自账户编号”)字符串来自账户编号,
@字段(“至账户编号”)字符串至账户编号,
@字段(“金额”)字符串金额);
帐户服务(注意:返回可观察到的改装):

@FormUrlEncoded@POST(“/user/accounts”)
公共可观察getAccounts(@Field(“session_id”)字符串sessionId);
将两个改装产生的可观察对象链接在一起:

transfersService.transfer(session.getSessionId(), fromAccountNumber, toAccountNumber, amount)
            .flatMap(new Func1<TransferResponse, Observable<? extends List<Account>>>() {
                @Override public Observable<? extends List<Account>> call(TransferResponse transferResponse) {
                    return accountsService.getAccounts(session.getSessionId());
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
transfersService.transfer(session.getSessionId(),从AccountNumber到AccountNumber,金额)

.平面图(new Func1答案是肯定的,您应该能够从改造中链接可观察对象。MockRestapter$MockRxSupport:createMockObservable私有类中似乎有一个bug。订阅订阅对象的调度方式似乎是错误的。订阅可观察对象在HttpExecutu中紧跟其后tor线程本身已启动。我相信来自Schedulers.io()线程的原始流已完成并取消订阅,然后才能订阅mockHandler.invokeSync returned Observable。如果您查看改装模拟模块中的代码,希望此解释有一定的意义

作为当前代码的一种解决方法,在使用改装模拟时,只有您可以使用自己的ImmediateExecutor实现替换内部默认执行器。这至少允许在测试模拟时使用Schedulers.io提供的单线程流

// ImmediateExecutor.java
public class ImmediateExecutor implements Executor {
    @Override
    public void execute(Runnable command) {
        command.run();
    }
}

// Create your RestAdapter with your ImmdiateExecutor
RestAdapter adapter = new RestAdapter.Builder()
            .setEndpoint(endpoint)
            .setExecutors(new ImmediateExecutor(), null)
            .build();
至于在源代码处修复问题,您还可以将改装模拟项目作为源代码包含在项目中,并使用下面的代码修改mockrestapter$MockRxSupport:createMockObservable方法。我已经测试了您的用例,它确实修复了问题

---java$MockRxSupport----

Observable createMockObservable(最终MockHandler MockHandler,最终RestMethodInfo methodInfo,
最终请求拦截器拦截器,最终对象[]args){
返回Observable.create(newobservable.OnSubscribe(){

@Override public void call(最终订阅)您使用的是哪个版本的改型和rxjava?这很有道理,我自己也很想知道,但由于我同时学习了改型和Rx,我觉得我只是做错了。感谢您提交错误,我将跟踪它,看看会发生什么。没问题,很高兴我能提供帮助。
transfersService.transfer(session.getSessionId(), fromAccountNumber, toAccountNumber, amount)
            .flatMap(new Func1<TransferResponse, Observable<? extends List<Account>>>() {
                @Override public Observable<? extends List<Account>> call(TransferResponse transferResponse) {
                    return accountsService.getAccounts(session.getSessionId());
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
@FormUrlEncoded @POST("/user/accounts")
public List<Account> getAccountsBlocking(@Field("session_id") String sessionId);
transfersService.transfer(session.getSessionId(), fromAccountNumber, toAccountNumber, amount)
            .flatMap(new Func1<TransferResponse, Observable<? extends List<Account>>>() {
                @Override public Observable<? extends List<Account>> call(TransferResponse transferResponse) {
                    return Observable.create(new Observable.OnSubscribe<List<Account>>() {
                        @Override public void call(Subscriber<? super List<Account>> subscriber) {
                            List<Account> accounts = accountsService.getAccountsBlocking(session.getSessionId());
                            subscriber.onNext(accounts);
                            subscriber.onCompleted();
                        }
                    });
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
// ImmediateExecutor.java
public class ImmediateExecutor implements Executor {
    @Override
    public void execute(Runnable command) {
        command.run();
    }
}

// Create your RestAdapter with your ImmdiateExecutor
RestAdapter adapter = new RestAdapter.Builder()
            .setEndpoint(endpoint)
            .setExecutors(new ImmediateExecutor(), null)
            .build();
Observable createMockObservable(final MockHandler mockHandler, final RestMethodInfo methodInfo,
        final RequestInterceptor interceptor, final Object[] args) {
      return Observable.create(new Observable.OnSubscribe<Object>() {
        @Override public void call(final Subscriber<? super Object> subscriber) {
          try {
            if (subscriber.isUnsubscribed()) return;
            Observable observable =
                (Observable) mockHandler.invokeSync(methodInfo, interceptor, args);

            observable.subscribeOn(Schedulers.from(httpExecutor));

            //noinspection unchecked
            observable.subscribe(subscriber);

          } catch (RetrofitError e) {
            subscriber.onError(errorHandler.handleError(e));
          } catch (Throwable e) {
            subscriber.onError(e);
          }
        }
      });
    }