Right way of using RxJava + Retrofit 2

≡放荡痞女 提交于 2021-02-06 13:48:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!