Rx和Retrofit:在repeatwhen或repeatuntill启动的请求循环中更改ServiceApi请求参数

时间:2016-12-12 10:34:29

标签: android rx-java retrofit2

我正在为我的应用程序使用retrofit和RxJava。 我正在执行一个请求,每1秒就会命中一次服务器。为此,我使用请求参数创建改装服务API并订阅返回的observable并使用repeatWhen。

问题是,每次命中请求时,我都想更改随请求发送的请求参数(基本上必须使其动态化)。我怎样才能做到这一点?

例如用例:sendLocation Api每10秒向服务器发送一个currrent位置。这可以通过改造和RxJava来实现这个目标

3 个答案:

答案 0 :(得分:3)

如果你添加延迟,

@TassosBassoukos的答案是有效的。具体来说,这是一个完整的例子,使用github API来交替两个用户之间的呼叫。确保不要让它运行太久 -

public interface GitHubService {
    @GET("/users/{user}/repos")
    Observable<String> getRepo(@Path("user") String user);
}

static String[] users = {"octocat", "square"};
static int i = 0;

static String getUser() {
    return users[i++ % 2];
 }

public void RxGitRepo() {
    OkHttpClient client = new OkHttpClient();

    Retrofit retrofit = new Retrofit.Builder()
      .client(client)
      .baseUrl("https://api.github.com")
      .addConverterFactory(ScalarsConverterFactory.create())
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
      .build();

   GitHubService gitHubService = retrofit.create(GitHubService.class);
   Observable
      .defer(() -> Observable.just(getUser()))
      .flatMap(user -> gitHubService.getRepo(user))
      .repeatWhen(done -> done.delay(2, TimeUnit.SECONDS))
      .subscribeOn(Schedulers.io())
      .subscribe(System.out::println);
}

对于您的用例,您可以每隔10秒轮询一次该位置,而不是在该位置设置您的observable并使用它来触发更新。使用android-reactiveLocation之类的库,您可以获得一个流式传输位置的Observable。以下未经测试的代码 -

LocationRequest request = LocationRequest.create() 
                             .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                             .setInterval(10000);

ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(context);
Subscription subscription = locationProvider.getUpdatedLocation(request)
    .sample(10, TimeUnits.SECONDS)
    .flatMap(/* your retrofit call based on the observed location */)  
    .subscribe(/* subsciber for retrofit call results */);

答案 1 :(得分:2)

这个怎么样?

    AtomicInteger requestParam = new AtomicInteger();

    apiCall.request(requestParam)
            .doOnNext(response -> requestParam.set(response.getRequestParam()))
            .repeatWhen(objectObservable -> objectObservable
                    .delay(1, TimeUnit.SECONDS)
                    .flatMap(o -> Observable.just(requestParam.get())
                    .takeWhile(integer -> /* condition */ )));

答案 2 :(得分:1)

使用类似的东西:

Observable
.defer(() -> Observable.just(getLocation))
.flatMap(location -> doNetworkCall(location))
.repeatWhen(...)