RxJava+Retrofit Samples 분석

7764 단어
버림선 대신이 쓴 예시 코드: RxJavaSamples apk 다운로드 주소: RxJavaSamples.apk는 코드만 보면 알아볼 수 있지만 자기가 쓰기에는 역부족이어서 코드 해석을 기록해 인상을 깊게 하기로 했습니다.

1. 기본 사용


RxJava와 Retrofit를 결합하면 가장 기본적인 형식을 사용합니다. subscribeOn()observeOn() 로 라인을 제어하고 subscribe() 를 통해 네트워크 요청의 시작을 터치합니다.코드의 대략적인 형식:
api.getData()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(observer);

여기서 observer는 (다음 예에서 observer는 기본적으로 동일하여 더 이상 열거하지 않음)입니다.
Observer> observer = new Observer>() {
        @Override
        public void onCompleted() {
        }

        @Override
        public void onError(Throwable e) {
              //    
            swipeRefreshLayout.setRefreshing(false);
            Toast.makeText(getActivity(), R.string.loading_failed, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onNext(List images) {
             //    
            swipeRefreshLayout.setRefreshing(false);
            adapter.setImages(images);
        }
    };

2. 변환(map)


일부 서비스 측의 인터페이스 디자인은 되돌아오는 데이터 외부에 추가 정보를 감싸는데, 이러한 정보는 디버깅에 매우 유용하지만, 로컬 디스플레이에는 쓸모가 없다.map()를 사용하면 바깥쪽의 포맷을 벗기고 로컬에서 사용할 핵심 포맷만 남길 수 있습니다.물론 map()도 다른 다양한 수요를 바탕으로 하는 형식 변환에 사용할 수 있다.코드의 대략적인 형식:
api.getData()
    .map(response->response.data)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(observer);

3. 누르기(zip)


때때로 app에서 서로 다른 인터페이스를 동시에 방문한 다음에 결과를 섞은 후에 통일된 형식으로 출력해야 한다(예를 들어 제3자 광고 API의 광고를 자신의 플랫폼에서 되돌아오는 데이터List에 섞는 것).이런 병행적인 비동기 처리는 비교적 번거롭지만 zip()를 사용한 후에는 훨씬 간단해질 것이다.코드의 대략적인 형식:
Observable.zip(api.getData(),adApi.getAds(),zipFunc())
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(observer);

4. 일회용 Token(flatMap)


보안, 성능 등의 측면에서 볼 때 대부분의 서버는 token을 전송해야 결과를 정확하게 되돌릴 수 있고 token은 다른 인터페이스에서 가져와야 하기 때문에 두 단계의 연속적인 요청을 사용해야 데이터를 얻을 수 있다(① token ->② 목표 데이터).flatMap()를 사용하면 비교적 뚜렷한 코드로 이러한 연속 요청을 실현할 수 있고Callback이 끼워 넣는 구조를 피할 수 있다.코드의 대략적인 형식:
api.getToken().flatMap(token -> api.getData(token))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(observer);

5. 비일회성 토큰(retryWhen)


어떤 토큰은 일회용이 아니라 시간이 초과되거나 소각될 때까지 여러 번 사용할 수 있다. (대부분의 토큰은 이렇다.)이러한 Token은 처리하기가 비교적 번거롭다. 그것을 저장하고, 효력을 상실한 것을 발견할 때 자동으로 새로운 Token을 다시 가져와 방문하기 전에 Token이 효력을 상실하여 실패한 요청을 계속해야 한다.프로젝트에 여러 개의 인터페이스 요청이 이러한 자동 복구 메커니즘을 필요로 한다면 전통적인 콜백 형식을 사용하려면 매우 복잡한 코드를 써야 한다.RxJava를 사용하면 retryWhen () 으로 이런 문제를 쉽게 처리할 수 있습니다.코드의 대략적인 형식:
api.getData(token)
    .retryWhen(observable ->
        observable.flatMap( ->
            api.getToken()
                .doOnNext(->updateToken())))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(observer);

위의 몇 가지 예는 모두 비교적 간단하지만 이것은 약간 복잡하기 때문에 구체적인 코드는 다음과 같다.
 subscription = Observable.just(null)
                .flatMap(new Func1>() {
                    @Override
                    public Observable call(Object o) {
                        //  cachedToken    
                        //        error observable
                        //      token     
                        return cachedFakeToken.token == null
                                ? Observable.error(new NullPointerException("Token is null!"))
                                : fakeApi.getFakeData(cachedFakeToken);
                    }
                })
                .retryWhen(new Func1, Observable>>() {
                    @Override
                    public Observable> call(Observable extends Throwable> observable) {
                        return observable.flatMap(new Func1>() {
                            @Override
                            //       error Observable
                            public Observable> call(Throwable throwable) {
                                if (throwable instanceof IllegalArgumentException || throwable instanceof NullPointerException) {
                                    //    token,           token      
                                    return fakeApi.getFakeToken("fake_auth_code")
                                            .doOnNext(new Action1() {
                                                @Override
                                                public void call(FakeToken fakeToken) {
                                                    tokenUpdated = true;
                                                    cachedFakeToken.token = fakeToken.token;
                                                    cachedFakeToken.expired = fakeToken.expired;
                                                }
                                            });
                                }
                                //    
                                return Observable.just(throwable);
                            }
                        });
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);

6. 캐시(BehaviorSubject)


RxJava에는 비교적 적게 사용되는 클래스Subject가 있는데 이것은'Observable이자 Observer'라는 것이기 때문에 중간부품으로 데이터 전달을 할 수 있다.예를 들어, 그것의 하위 클래스 BehaviorSubject 로 캐시를 만들 수 있다.코드의 대략적인 형식:
api.getData().subscribe(behaviorSubject); //   cache       ,        
behaviorSubject.subscribe(observer);//           observer

구체적인 예:
BehaviorSubject> cache;
public Subscription subscribeData(@NonNull Observer> observer) {
         //          
        if (cache == null) {
            cache = BehaviorSubject.create();
            Observable.create(new Observable.OnSubscribe>() {
                @Override
                public void call(Subscriber< ? super List> subscriber) {
                    List items = Database.getInstance().readItems();
                    //          
                    if (items == null) {
                        //       
                        loadFromNetwork();
                    } else {
                        //      
                        subscriber.onNext(items);
                    }
                }
            }).subscribeOn(Schedulers.io())
              .subscribe(cache);
        } 
        return cache.observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
    }

  subscription = subscribeData(new Observer>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        swipeRefreshLayout.setRefreshing(false);
                        Toast.makeText(getActivity(), R.string.loading_failed, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onNext(List items) {
                        swipeRefreshLayout.setRefreshing(false);
                        adapter.setItems(items);
                    }
                });

좋은 웹페이지 즐겨찾기