LiveData with RxJava2

LiveData with RxJava2

shibuya.apk #16 の発表資料です。
https://shibuya-apk.connpass.com/event/59671/

42df16a50ca7bc63507e17f07b711701?s=128

Tatsuya Kitagawa

June 22, 2017
Tweet

Transcript

  1. -JWF%BUB XJUI3Y+BWB TIJCVZBBQL !ZBUBUTV

  2. ࣗݾ঺հ w๺઒ୡ໵ʢ,*5"("8"5BUTVZBʣ wגࣜձࣾΞϐϦοπ w"OESPJEΞϓϦͷडୗ։ൃ w(JU)VC!ZBUBUTV

  3. -JWF%BUBͱ͸ʁ w(PPHMF*0Ͱൃද͞Εͨ
 "OESPJE"SDIJUFDUVSF$PNQPOFOU
 ͷػೳͷͻͱͭ w6*ͷϥΠϑαΠΫϧΛߟྀͨ͠
 σʔλͷมߋ؂ࢹ wݱ࣌఺ͷόʔδϣϯ͸BMQIB

  4. PCTFSWF -JGFDZDMF0XOFS  0CTFSWFS5 LiveData<String> textLiveData = viewModel.getMessage(); textLiveData.observe(this, text

    -> { // ͜͜͸ΞΫςΟϒͳͱ͖͚ͩݺ͹ΕΔ textView.setText(text); }); •LifecycleOwnerʹ͸ී௨Activity΍Fragment •UI͕ΞΫςΟϒͳঢ়ଶʢSTARTED, RESUMEDʣͰͷΈɺ
 σʔλͷมߋΛड͚औΔ͜ͱ͕Ͱ͖Δ
  5. "OESPJE"SDIJUFDUVSF $PNQPOFOU 3&45"1* -PDBUJPO4FSWJDF %BUBCBTF 3FQPTJUPSZ 7JFX.PEFM -JWF%BUB5 -JWF%BUB5 "DUJWJUZ


    'SBHNFOU
  6. 3Y+BWBΛ͋Θͤͨߏ੒ 3&45"1* -PDBUJPO4FSWJDF %BUBCBTF -JWF%BUB5 'MPXBCMF5
 4JOHMF5
 $PNQMFUBCMF 3FQPTJUPSZ "DUJWJUZ


    'SBHNFOU 7JFX.PEFM
  7. 3Y+BWBUP-JWF%BUB "android.arch.lifecycle:reactivestreams:1.0.0-alpha3" LiveDataReactiveStreams.fromPublisher(Publisher) •RxJava2ͱͷม׵ϝιου͕༻ҙ͞Ε͍ͯΔ

  8. GSPN1VCMJTIFS 1VCMJTIFS ʢൈਮʣ public static <T> LiveData<T> fromPublisher(final Publisher<T> publisher)

    { MutableLiveData<T> liveData = new MutableLiveData<>(); final WeakReference<MutableLiveData<T>> liveDataRef = new WeakReference<>(liveData); publisher.subscribe(new Subscriber<T>() { @Override public void onSubscribe(Subscription s) { s.request(Long.MAX_VALUE); } @Override public void onNext(final T t) { final LiveData<T> liveData = liveDataRef.get(); if (liveData != null) { liveData.postValue(t); } }
  9. εέδϡʔϥʹؾΛ͚ͭΔ •LiveData<T>#postValue(T) •λεΫΛϝΠϯεϨου্Ͱ࣮ߦ͢Δ •LiveData͸ϝΠϯεϨουͰͷಈ࡞͕جຊ •ϝΠϯεϨουͰॲཧ͞ΕΔલʹɺ
 ෳ਺postValue͞ΕΔͱ࠷৽ͷ஋ͷΈૹ৴

  10. GSPN1VCMJTIFS 1VCMJTIFS ʢൈਮʣ public static <T> LiveData<T> fromPublisher(final Publisher<T> publisher)

    { // … publisher.subscribe(new Subscriber<T>() { // … @Override public void onError(Throwable t) { // Errors should be handled upstream, so propagate as a crash. throw new RuntimeException(t); } @Override public void onComplete() { } }); return liveData; }
  11. -JWF%BUBͷΤϥʔॲཧ •LiveData͸ྫ֎ΛϋϯυϦϯά͠ͳ͍ •ม׵͢Δࡍʹ͸ΤϥʔΛϥοϓ͢Δඞཁ͕͋Δ

  12. -JWF%BUBͷΤϥʔॲཧʢྫʣ // TODOΛDB͔Βऔಘ͢Δαϯϓϧ // ্ྲྀͰΤϥʔ͕͋ͬͨͱ͖ʹͦͷ··ྫ֎Λ౤͛Δ LiveData<List<Todo>> getTodos(TodoStatus status) { Flowable<List<Todo>>

    list = todoDb.todoDao().findByStatus(status) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); return LiveDataReactiveStreams.fromPublisher(list); }
  13. -JWF%BUBͷΤϥʔॲཧʢྫʣ public class LoadState<T> { private boolean loading; private T

    data; private Throwable error; public LoadState(boolean loading, @Nullable T data, @Nullable Throwable error) { this.loading = loading; this.data = data; this.error = error; }
  14. -JWF%BUBͷΤϥʔॲཧʢྫʣ LiveData<LoadState<List<Todo>>> getTodos(TodoStatus status) { Flowable<LoadState<List<Todo>>> state = todoDb.todoDao().findByStatus(status) .map(LoadState::data)

    // औಘ੒ޭ .onErrorReturn(LoadState::error) // Τϥʔ .startWith(LoadState.loading()) // ϩʔσΟϯά .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); return LiveDataReactiveStreams.fromPublisher(state); }
  15. JPSFBDUJWFY$PNQMFUBCMF •onComplete, onError •ฦΓ஋Λ΋ͨͣ݁Ռͷ׬ྃɺࣦഊ͚ͩΛ஌Γ͍ͨͱ ͖ʹར༻͞ΕΔ •REST APIͷPOST, ϩʔΧϧσʔλͷ࡟আͳͲ

  16. $PNQMFUBCMFUP-JWF%BUB •LiveDataͰදݱ͍ͨ͠ •Flowableʹม׵͢Δ •׬ྃ/ࣦഊΛΦϒδΣΫτͰද͢

  17. ࣦഊɾ׬ྃΛද͢ΦϒδΣΫτ public interface AddTodoState { final class None implements AddTodoState

    {} final class Loading implements AddTodoState {} final class Error implements AddTodoState { final Throwable throwable; public Error(Throwable throwable) { this.throwable = throwable; } public Throwable getThrowable() { return throwable; } } final class Complete implements AddTodoState {} }
  18. $PNQMFUBCMFUP-JWF%BUB MutableLiveData<AddTodoState> addTodoState = new MutableLiveData<>(); Completable completable = todoRepository.addTodo(todo);

    Disposable disposable = completable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .toSingle(AddTodoState.Complete::new) .toObservable() .cast(AddTodoState.class) .onErrorReturn(AddTodoState.Error::new) .startWith(new AddTodoState.Loading()) .subscribe(addTodoState::setValue);
  19. ·ͱΊ w 3Y+BWB͔Β-JWF%BUBʹม׵͕Ͱ͖Δ w -JWF%BUB͸ϝΠϯεϨου͕جຊͳͷͰ
 ม׵͢Δͱ͖εέδϡʔϥʹؾΛ͚ͭΔ w ΤϥʔΛϥοϓͨ͠ΦϒδΣΫτΛ஋ʹ͢Δ w $PNQMFUBCMF͸ঢ়ଶΛ஋ʹ͢Δ

  20. ࢀߟϦϯΫ w αϯϓϧίʔυ
 IUUQTHJUIVCDPNZBUBUTVBOESPJEBSDIUPEPTBNQMF w ެࣜͷαϯϓϧϦϙδτϦ
 IUUQTHJUIVCDPNHPPHMFTBNQMFTBOESPJEBSDIJUFDUVSFDPNQPOFOUT USFFNBTUFS(JUIVC#SPXTFS4BNQMF w (PPHMF*0ͷηογϣϯ


    "SDIJUFDUVSF$PNQPOFOUT4PMWJOHUIF-JGFDZDMF1SPCMFN (PPHMF*0  :PV5VCF
 IUUQTXXXZPVUVCFDPNXBUDI WC&,/J+0S/T w ެࣜυΩϡϝϯτ
 -JWF%BUBc"OESPJE%FWFMPQFST
 IUUQTEFWFMPQFSBOESPJEDPNUPQJDMJCSBSJFTBSDIJUFDUVSFMJWFEBUBIUNM
  21. ͓ΘΓ w͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ