I am building an android application. In which in need to handle multiple api calls in queue to avoid collision using retrofit and also i need to manage this in common Applicationclass. It is possible?
You can achieve this using RxJava and Retrofit. RxJava provides us zip operator.
Sample code for this would be in your repository class
Observable.zip(
getCricketFansObservable(),
getFootballFansObservable(),
BiFunction<List<User>, List<User>, List<User>> { cricketFans, footballFans ->
// here we get both the results at a time.
return#BiFunction filterUserWhoLovesBoth(cricketFans, footballFans)
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver())
Related
I am working on an application, where I had used Rx-android and Retrofit to do the network request, but now there is a requirement in the project where I have to do the nested network calls.I tried to google it out but didn't found any good article.If any one has worked on such topic then please let me know your findings.
Assuming you're using retrofit with the rxjava adapter:
fun firstRequest(): Single<Response<String>>
fun secondRequest(idFromFirstRequest: String): Single<Response<ResponseBody>>
Use flatmap operator to chain the network calls:
firstRequest()
// do more operators on the request, like transforming the object, or showing it first on the ui
.flatMap { stringId -> secondRequest(stringId) }
// you can flatMap here again to chain another network requests
// .flatMap { thirdRequest() }
// .flatMap { fourthRequest() }
// and so on...
There are various articles related to API chaining, and the easiest way to achieve is using Rx-Java approaches
1) Using RxJava Zip operator (for parallel requests)
2) Using RxJava flatMap() operator(To request serially one after another)
Refer these two links for more detail examples
Synchronizing Network Calls With RxJava
Multiple api request using retrofit and rx java
I am new to Kotlin, coming from C# it I am quite used to async\await
How do I wait for tvClient to get the response before returning the list of channels?
override fun getChannels(): MutableList<Channel> {
disposable = tvClient.getChannels()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{Log.d("***", it.toString())},
{Log.d("***",it.toString())}
)
TODO("wait for tvClient to return results")
return mChannels;
}
I tried using coroutines but no luck
What is the best way to wait for async operation to complete in Kotlin?
You're using RxJava and thus you should implement it in a reactive way.
If you're app is not build for it yet, you can get the value blocking. Assuming getChannels() returns a single you could just call blockingGet() instead of subscribe().
But be aware that this blocks the thread the outer getChannels() is called from.
Using coroutines might be better for you. It's a little nearer to what you know from C# and with the retrofit2-kotlin-coroutines-adapter you can integrate directly with Retrofit.
You could look into using the retrofit coroutine adapters from Jake Wharton https://github.com/JakeWharton/retrofit2-kotlin-coroutines-adapter
you can check a functional implementation of kotlin v1.3 retrofit + stable coroutines using DSL here https://github.com/eriknyk/networkcall-sample/commits/master
DSL template:
fun <RESPONSE: DataResponse<*>, DATA: Any> networkCall(block: CallHandler<RESPONSE, DATA>.() -> Unit): MutableLiveData<Resource<DATA>>
= CallHandler<RESPONSE, DATA>().apply(block).makeCall()
interface DataResponse<T> {
fun retrieveData(): T
}
and using it:
fun getRepos(query: String) = networkCall<ResposResponse, List<Repo>> {
client = githubService.getRepos(query)
}
Hope it helps.
AFAAIK, Retrofit uses RxJava internally.Then what is the advantage of integrating Retrofit with RxJava externally like here, if I don't want to filter,sort or modify the data received from api?Does it reduces the time for fetching response from api?In what way does it helps in improving performance of our api calls?
Retrofit started as project before RxJava and you used to retrieve the API via callbacks. Then came RXJava and a more strict integration between the two was possible. So that you change Call<T> with an Observable/Flowable interface, and instead to use a call back into the code you retrieve the result directly exploiting the power of the reactive paradigm.
Please consider you have to specify you are using RXJava when you build Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl);
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//here
.addConverterFactory(GsonConverterFactory.create())
.build();
Saying that RXJava implements internally Retrofit is kind of tricky, Retrofit remain indipendent, just RXJava offers some binding code so that you can adapt Retrofit2 to be an Observable.
This code taken from here, explain how to bind the two
public interface UserService {
#POST("/me")
Observable<User> me();
}
// this code is part of your activity/fragment
Observable<User> observable = userService.me();
observable
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<User>() {
#Override
public void onCompleted() {
// handle completed
}
#Override
public void onError(Throwable e) {
// handle error
}
#Override
public void onNext(User user) {
// handle response
}
});
Then you ask to many questions, in stackoverflow you get one reply per post.
Just please consider that the advantage of using RXJava and Retrofit integrated are a lot, for instance you have a come much more clean, testable and you do not have to consider concurrency issues. Regarding the performance I get is the same for a normal case.
EDIT:
To understand better when to use RXJAVA+Retrofit and when just Retrofit you can see this post
Outside from that content please consider that is really useful to see all the succesion in a functional way inside a single class, plus you have OnComplete, you can operate any sort of transformation.
Furthermore is much easier to combine multiple calls as here, the advantages are really clear in real life situations,
and also to do testing and maintain the code clean, that just taken alone these two, are two great advantages.
You also may want to explore the new Google Architecture functionalities components with Retrofit, where you can use both RXJava or LiveData
I am very new to using RxJava with Retrofit in Android. I have successfully written the API calls and developed the interface too. Now, I want to write my code in a way that I can send two requests: second request depending upon the values of first request. Can someone guide me if this is possible? If so then how? Any code snippet will really be helpful.
For example: following are two requests:
mCompositeDisposable.add(fcService.getStationList()
.subscribeOn(Schedulers.io()) // "work" on io thread
.observeOn(AndroidSchedulers.mainThread()) // "listen" on UIThread
.subscribe(this::handleResults, this::handleError)
);
mCompositeDisposable.add(fcService.getStationSensor("12345678")
.subscribeOn(Schedulers.io()) // "work" on io thread
.observeOn(AndroidSchedulers.mainThread()) // "listen" on UIThread
.subscribe(this::handleResults, this::handleError)
);
Second request is possible with the value from the first request's response. Is it possible to merge these two requests in a way that I write code only once for them?
With the flatMap operator you can check the response of the first call and choose the next action to follow, in this way you build a new Observable that you can subscribe to (The next "code" is kotlin style):
Single<StationSensor> newSingle =
fcService.getStationList().flatMap{ stationList ->
when(stationList){
"OK_value" -> fcService.getStationSensor(stationList)
else -> Single.error(RuntimeException("Error response"))
}
}
I've been adapting my Android app to use RxJava but I'm having a little bit of trouble doing so. As I had been advised in a previous post (Wait for all requests in Android Volley), I'm using Observables to mimic how I'm interfacing with my REST API in JavaScript. Specifically, using the promise library, I compose calls like this:
$q.all([
fetchResourceA(),
fetchResourceB()
])
.then(function (responses) {
...
return fetchResourceC();
})
.then(function (response) {
...
});
In this example, I query two resources simultaneously, collect the results, then collect a third resource based on some of the parameters from the previously collected resources. The best I've been able to do to mimic this in RxJava is like this:
Observable o = Observable.zip(
fetchResourceA(),
fetchResourceB(),
new Func2<ResA, ResB, Object>() {
#Override
public Object call(ResA resA, ResB resB) {
...
}
}
);
But I'm struggling to compose them like I did in JavaScript. Do I need to simply create a second observable and subscribe to it in the callback of the zip? That's what I'm doing now, and it works, but I'd like to know if there's a more elegant and more reactive-appropriate way to structure my requests.
The .then method from promise can be transposed to flatMap method in RxJava
So, what you can do, is to zip then flatMap then flatMap
Observable.zip(fetchA(), fetchB(), (a, b) -> new Response(a, b))
.flatMap((responses) -> fetchC())
.flatMap((cResponse) -> /* whatever */)
.subscribe();
Please note that fetchA(), fetchB(), fetchC() return Observables.
(My example use lambdas for clarity)