Reputation: 225
I am using retrofit and RxJava for my application. I am executing a request which will hit the server every 1 sec. For this, I create retrofit service API with request params and subscribe on the returned observable and use repeatWhen.
Problem is , every time the request is hit, I want to change the request parameter sent with the request(Basically have to make it dynamic). How can I achieve this?
For eg Use case: sendLocation Api sending currrent location to server every 10 sec. How can this be achive this using retrofit and RxJava
Upvotes: 3
Views: 1676
Reputation: 6839
How about this?
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 */ )));
Upvotes: 2
Reputation: 31996
@TassosBassoukos' answer works if you add the delay in. Specifically, here is a full example using github API that alternates calls between two users. Make sure not to let this run too long --
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);
}
For your use case, instead of polling the location every 10 seconds, you could set up your observable on the location and use that to trigger updates. Using a library like android-reactiveLocation, you can get an Observable
that streams locations. Something along the lines of the following untested code --
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 */);
Upvotes: 5
Reputation: 16142
Use something like this:
Observable
.defer(() -> Observable.just(getLocation))
.flatMap(location -> doNetworkCall(location))
.repeatWhen(...)
Upvotes: 1