RxJava로 모델, 캐시, 페이지 스타일, 그리고


나는 어떻게 이 일련의 것을 실현할 것인가를 고려하고 있다.

전제 조건

  • REST API 사용
  • API 반환 데이터 모델 + 메타데이터
  • 모델도 메모리 캐시 및 파일 캐시에 해당
  • 모델과 응답의 형식


    메타데이터에는 페이지 정보 등 서버/클라이언트에서 데이터를 교환하는 데 필요한 데이터가 포함되어 있습니다.
    메타데이터를 모델 밖으로 가져오려고 리스폰스 클래스에 모델 레이어를 씌웠다.페이지 스타일을 설정합니다.
    public class Response<T> {
        private T result;
        private Extra extra;
        private Observable<Response<T>> next;
    
        public T getResult() {
            return result;
        }
    
        public Extra getExtra() {
            return extra;
        }
    
        public int nextPage() {
            return extra.getLinks().getNext().getPage();
        }
    
        public Observable<Response<T>> getNext() {
            return next;
        }
    
    Response#getNext 다음 페이지에서 참고를 요청할 수 있는 느낌을 준다.

    모델 액세스


    서비스 유형을 구축하여 추상적인 모델로 목적지를 얻다.
    new RecipeService().search("tapas", 1); // どこかからかモデルが返ってくる
    
    RecipeService#search 캐시를 찾을 수 없으면(현재 구현되지 않았지만) 결과를 반환하려면 API를 두드립니다.
    응답을 받으면 다음 페이지의 Observable을 만들어 설정합니다.
    따라서 목록의 끝까지 스크롤할 때Response#getNext 다음 페이지를 요청할 수 있습니다.
    public Observable<Response<List<Recipe>>> search(final String keyword, final int page) {
        String path = String.format("/recipes?keyword=%s&page=%s", keyword, page);
        return request(Method.GET, path, null, null, new TypeToken<Response<List<Recipe>>>() {
        }).map(new Func1<Response<List<Recipe>>, Response<List<Recipe>>>() {
            @Override
            public Response<List<Recipe>> call(Response<List<Recipe>> r) {
                r.setNext(search(keyword, r.nextPage()));
                return r;
            }
        });
    }
    
    public <T> Observable<T> request(Method method, String path, Map<String, String> headers, RequestBody body, TypeToken<T> type) {
        return Observable.create(new RequestSubscriber<>(method, path, headers, body, type))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
    
    덧붙여 안드로이드는 자바 7로 쓰거나 자바 8은 사용할 수 없기 때문에 라마다가 아닌 펀치1과 액션 1 등을 계승해 사용할 수 있다.
    그러나 Retrolambda와 같은 가방 도구를 사용하면 고무 등 일부 기능을 사용할 수 있다.

    목록 및 데이터 어댑터


    먼저 Controller에서 키워드를 건네주고 어댑터를 초기화합니다.
    SearchResultAdapter searchResultAdapter = new SearchResultAdapter(this);
    searchResultAdapter.search("tapas");
    
    어댑터가 키워드를 받은 후 Subject를 생성합니다.그 다음에 활동용으로 불이 났어요.
    응답을 받았을 때 다음 페이지의 Observable이 있기 때문에 유지해야 합니다.
    public void search(String keyword) {
        responseSubject = BehaviorSubject.create(new RecipeService().search(keyword, 1));
        responseSubject.flatMap(new Func1<Observable<Response<List<Recipe>>>, Observable<Response<List<Recipe>>>>() {
            @Override
            public Observable<Response<List<Recipe>>> call(Observable<Response<List<Recipe>>> r) {
                return r;
            }
        }).subscribe(new Action1<Response<List<Recipe>>>() {
            @Override
            public void call(Response<List<Recipe>> r) {
                recipes.addAll(r.getResult());
                notifyDataSetChanged();
    
                pagedResponse = r.getNext();
            }
        });
    }
    

    다음 페이지 요청


    끝까지 굴러갔을 때 불이 났다.
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        ...
        if (recipes.size() - 1 == i) {
            responseSubject.onNext(pagedResponse);
        }
    

    잡감


    RxJava가 최근에 유행하는 것 같아서RxJava Night #rxjnight - connpass 가져오기 여부를 판단하기 위해 실용적인 용례를 사용할 수 있는지 검토 중입니다.
    RxJava 사용으로 에이전트머스크로더(AsyncTaskLoader) 등 보일러판을 쓰는 작업에서 해방될 뿐만 아니라 데이터와 이벤트를 추상적으로 처리해 보다 쉽게 처리하고 본질적인 처리에 집중할 수 있다.
    다른 한편, RxJava를 가져와서 발생하는 새로운 복잡도에 어떻게 대처해야 하는지도 고려한다.
    어제 RxJava에 대한 지식을 찾기 위해 인터넷에서 수영을 하다가 RxJava를 도입한 것을 발견하고 엘리 프롬프트 and sleepless nights뉴스.가 되어 온몸을 떨었다.
    아마도 상술한 인코딩도 현지의 unsubscribe에 적합하지 않을 것 같습니다.
    지금까지도 몇 개의 라이브러리와 프레임워크 도입에 실패한 적이 있기 때문에 이번에도 신중하게 논의를 하고 있지만 호기심에 밀려 도입했다고 생각한다.

    좋은 웹페이지 즐겨찾기