2015-12-12 32 views
16

Wciąż próbuję RxJava i używam go do robienia sieci z Retrofit 2. Próbowałem go przez kilka dni i jak teraz kod wygląda na bardziej czytelny, ale natrafił na problem, który wydaje mi się nie pasować.RxJava ponownie subskrybuj wydarzenie po przywróceniu aktywności

Próbuję wykonać logowanie (które zwraca token API), a następnie użyć tego tokena do pobrania początkowych danych w tym samym łańcuchu, tak aby wyjście łańcucha było tokenem + danymi. Aby to zrobić, ja nazywam moją usługę API z

apiClient 
    .login() 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .flatMap(token -> getData(token)) 
    .subscribe(new Subscrber<Bundle>() {...}); 

to wydawało się w porządku, ale chciałem też pokazać pasek postępu podczas uruchamiania i zatrzymywania łańcucha. Dlatego dodałem do tego również .doOnSubscribe() i .doOnUnsubscribe(). Jednak zauważyłem, że po zmianie orientacji fragment, który próbowałem ukryć pasek postępu jest zawsze pusty.

Poszukałem więc i natknąłem się na bibliotekę RxLifecycle, która wydawała mi się pomocna i teraz .cache() i wypisz się z łańcucha zdarzeń. Ale nie mogę po tym dowiedzieć się, jak zasubskrybować to samo wydarzenie w onCreate()? Myślę, że brakuje mi czegoś bardzo prostego i będę wdzięczny za każdą pomoc.

+1

Najlepsze, co można zrobić, to podzielić logikę i wdrożyć wzór 'MVP'. Po tym, klasa 'Presenter' (która idealnie powinna być pojedynczą instancją na widok) obsłuży całą sieć i zachowa odbudowę widoku po obróceniu ekranu. W rzeczywistości istnieje całkiem schludna biblioteka, która pozwala na użycie wzorca MVP opartego na rxJava https://github.com/konmik/nucleus (jest naprawdę mały). Nawet jeśli nie chcesz go używać, możesz się zorientować, w jaki sposób można go zaimplementować: – Than

+0

hmm .. ok, więc sądzę, że muszę przeczytać dobrą implementację MVP, zanim zejdę z trasy RxJava ... –

+1

'MVP' może sprawić, że twój kod stanie się znacznie bardziej przejrzysty i rozwiąże ten problem, ale może nie jest to rozwiązanie, którego szukasz (nie jest tak łatwo przełączyć architekturę całej aplikacji na MVP) (dlatego nie opublikowałem tego jako odpowiedź). Jestem pewien, że istnieje sposób, aby to zrobić bez 'MVP' przy użyciu biblioteki trzeciej strony lub kilku ładnych wzorów, ale nie miałem żadnego czystego rozwiązania. Traktuj mój powyższy komentarz jako "jak inni radzą sobie z podobnym problemem". – Than

Odpowiedz

0

Musisz upewnić się, że subskrybować samo obserwowalnych przykład, który jest zwracany z .cache(). Zazwyczaj przechowujesz tę instancję gdzieś w Singleton (jak klasa aplikacji), zatrzymany fragment lub usługę Android.

+0

Bądź jednak ostrożny, ponieważ cache() również buforuje błędy! – scana

1

Nie musisz koniecznie używać żadnego wzorca architektury, aby to osiągnąć. Chociaż dowolne MVP/MVC są fajnymi rzeczami do separacji, testowania itp., Sprawienie, że Twój kontroler/prezenter/DAO w całej aplikacji, który utrzymuje pamięć przez całe życie aplikacji, nie jest dobrym pomysłem.

Oto przykładowy projekt z użyciem zatrzymany instancji fragmentem i RxJava - https://github.com/krpiotrek/RetainFragmentSample

Główną ideą jest użycie fragmentu z setRetainInstance (prawdziwego) nazwie, która zabezpiecza go przed zniszczeniem na zmianę orientacji i przechowywania Obserwować tam. Oto w jaki sposób można obsłużyć, że w działalności/Fragment onCreate

protected void onCreate(Bundle savedInstanceState) { 
    if (savedInstanceState == null) { 
     // first run, create observable 
     mInfoObservable = createInfoObservable(); 
     // set Observable in retained fragment 
     RetainFragmentHelper.setObject(this, getSupportFragmentManager(), mInfoObservable); 
    } else { 
     // following runs, get observable from retained fragment 
     mInfoObservable = RetainFragmentHelper.getObjectOrNull(this, getSupportFragmentManager()); 
    } 

    // subscribe 
    mInfoObservable.subscribe(...); 
} 

Pamiętaj, że Obserwowalne musi buforować ostatnią wartość, jednym ze sposobów jest wykorzystanie pamięci podręcznej () operatora.