问题
I have such JSON:
{
"success":true,
"data":[
{
"id":"29",
"name":"\u0420\u0435\u0441\u0442\u043e\u0440\u0430\u0446\u0456\u044f \u0411\u0430\u0447\u0435\u0432\u0441\u044c\u043a\u0438\u0445 \/ Baczewski Restaurant",
"street":"\u0432\u0443\u043b. \u0428\u0435\u0432\u0441\u044c\u043a\u0430, 8",
"latitude":"49.842292845502",
"longitude":"24.029848249565",
"image":"https:\/\/i.onthe.io\/j9aocq72r2lfsmoh9.r500x500.01ff9fff.jpg"
},
...
]
}
According to it have to Classes
(pojo) created with schema to pojo. First one provides method to get data from data
array - >
public List<Datum> getData() {
return data;
}
And the second one is a model
of this data.
While using only retrofit 2.0 I perform a call
, parse each object
from the data
array and add it to RecyclerView.Adapter
Call<PlaceList> call = service.list(1, offset, 10);
call.enqueue(new Callback<PlaceList>() {
@Override
public void onResponse(Call<PlaceList> call, Response<PlaceList> response) {
final int size = response.body().getData().size();
for (int i = 0; i < size; i++) {
places.add(response.body().getData().get(i));
}
handler.post(new Runnable() {
@Override
public void run() {
if (offset == 0)
// adapter.notifyItemRangeInserted(0, foodDataList.size());
placeRecyclerAdapter.notifyDataSetChanged();
else
placeRecyclerAdapter.notifyItemRangeChanged(places.size() - size, places.size());
}
});
}
@Override
public void onFailure(Call<PlaceList> call, Throwable t) {
}
});
_______________
public interface Places {
@GET("places.getPlaces")
Call<PlaceList> list(
@Query("type") int type,
@Query("offset") int offset,
@Query("limit") int limit);
}
So this a usual way for me. Now I want to do the same using RxJava
.
Here is my interface
:
public interface Places {
@GET("places.getPlaces")
Observable<PlaceList> list(@Query("type") int type,
@Query("offset") int offset,
@Query("limit") int limit);
}
And this is how I perform call
:
Observable<PlaceList> call = service.list(1, offset, 10);
subscription = call.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<PlaceList>() {
@Override
public void onCompleted() {
System.out.println("onComplete");
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
e.printStackTrace();
}
@Override
public void onNext(PlaceList data) {
placeRecyclerAdapter.addData(data.getData());
}
});
Yeah, it's also works, but was it a right way of using Rx
? I tried to compare time needed for parsing, but didn't see any notable difference.
I'm just on my first day of studying RxJava, after reading few articles. So what is the right way to feel the power of RxJava
?
回答1:
You are using it correctly, RxJava has very much power which you can leverage in order to improve Performance.
Where to use? 1. On user events, like Button click, Key events 2. Respond to latency bound IO. Disk/network read/write 3. Events triggered by Hardware/sensors
Should not start Thread manually from Observable create.
Retrofit Network call with RxJava: Use Single : As our API will not give data in a pieces or multiple times. Instead it will emit everything in just one call. So, in case of Observable onCompleted() will follow as soon as onNext() happens. So, it would be better to use Single for API calling.
Use Completable : Whenever we need to just update data to Server through API, and We do not bother about what should be the result. We just meant if service is successful or not. In this cases we are not expecting to emit anything. So use of Completable is encouraged in the cases.
For progress view hide/show: Bind this two events with doOnSubscribe() and doFinally(). This are two operators, so we can logically bind them with RxCall.
RxJava Error Handling:
onErrorResumeNext( ) — instructs an Observable to emit a sequence of items (which is another observable)if it encounters an error
onErrorReturn( ) — instructs an Observable to emit a particular item when it encounters an error
onExceptionResumeNext( ) — instructs an Observable to continue emitting items after it encounters an exception (but not another variety of throwable)
retry( ) — if a source Observable emits an error, resubscribe to it in the hopes that it will complete without error. Here we can also pass argument for How many times retry should happen. Like. retry(4). It will retry four times and after that if again error occures then will throw an error.
retryWhen( ) — if a source Observable emits an error, pass that error to another Observable to determine whether to resubscribe to the source
RxAndroid for View Binding:
Think Reactive: We can use RxJava for all view events including click event, scroll event, drag event. In short, we can replace every Listeners with RxJava observables.
Available Libraries to use at View level: RxBinding, RxSupport-v4, RxAppCompat-v7, RxRecyclerView, RxDesign, RxLeanBack.
RxBinding with MVP: We will return Observable from View. This observable will fetch to Presenter and will do Subscription at Presenter.
RxAdapter: we can use this for data change event in Adapter. Typically available for Android Listview. RxRecyclerView: For recyclerview adapter data change events we can use this.
来源:https://stackoverflow.com/questions/37254039/right-way-of-using-rxjava-retrofit-2