ããã¯ãAndroid Cellsã«é¢ããäžé£ã®èšäºã®æåŸã®3çªç®ã®éšåã§ãã
äžè¬çã«ãAndroid SDKãRxJavaãDitches-å§ããŸãããïŒ
åã®ããŒãïŒ
1. actionLayoutãèšå®ãããŠããå Žåã Activity.onOptionsItemSelectedïŒïŒã¯åŒã³åºãããŸãã
ç¶æ³
ãã¹ãã¿ã¹ã¯ãå®è¡ãããã ããã¯éå±ã§å調ã§...å€ããã®ã§ããã ãšãŠãå€ãã PSDãåäžçŽã®ããã«ã ãŸãããã€ã³ãã§ã¯ãããŸããã ãã¹ãŠã®äž»èŠãªãã€ã³ããçµããã®ã§ãç§ã¯ãã¹ãŠã®ã€ã³ãã³ãïŒãããã³ã°ããã³ãå®èŠã«ãããšæãªããã®æ¹æ³ïŒãå·®ãåŒãããšãèšå®ããŸããã ã¢ããªã±ãŒã·ã§ã³ãšPSDã®ç»é¢ã§äžæå¿«ãªã¡ãã¥ãŒã®äžäžèŽãèŠã€ãããŸã§ãäºæ ã¯ããŸããããŸããã ã¢ã€ã³ã³ã¯åãã§ãããã ããã£ã³ã°ã¯åãã§ã¯ãããŸããã§ããã åéºå®¶ãšããŠãã¢ã€ã³ã³ãçž®å°ããŸããã§ãããã MenuItemã® actionLayoutããããã£ã䜿çšããããšã«ããŸããã å¿ èŠãªãã©ã¡ãŒã¿ãŒãå«ãæ°ããã¬ã€ã¢ãŠãããã°ããè¿œå ãããšãã¥ã¬ãŒã¿ãŒã®ã¢ã€ã³ã³ã®ã€ã³ãã³ããå確èªããŠããœãªã¥ãŒã·ã§ã³ãéä¿¡ããæ¥æ²¡ã«ãªããŸããã
ç¶æ³
çããæ¥ããšãã®é©ããæ³åããŠãã ããïŒéèªçïŒïŒãç·šéã¯æ©èœããŸãããã ãšããã§ãç§ã¯ãã®æ¹æ³ãšããã®äž¡æ¹ã§ã¢ããªã±ãŒã·ã§ã³ããã¹ãããŸããããäœããèŠéããŠã¯ãããŸããã§ããã ãããã¯ã¯ãŸããæ£ç¢ºã«äœãæ©èœããªãã£ãã®ããæ確ã§ã¯ãªãã£ãçãã®ç°¡æœãªåœ¢åŒã«ãã£ãŠæªåããŸãã...
...幞ããªããšã«ãç§ã¯é·ãéæ€çŽ¢ããå¿ èŠã¯ãããŸããã§ããã ã¿ã€ãã«ãããã§ã«æãããªããã«ãã«ã¹ã¿ã ã¬ã€ã¢ãŠããèšå®ããå Žåã onOptionsItemSelectedïŒïŒã¯åã«ç¡èŠãããŸã ã
ãªãã§ïŒ
ãã以æ¥ã Androidã§ã¯ãžã§ãŒã¯ãã²ã©ãããã¶ã€ã³ãå€æŽããŠãã¢ããªã±ãŒã·ã§ã³ã®åäœãå€åããå¯èœæ§ãããããšãã¯ã£ãããšèªèããŸããã ããŠããã€ãã®ããã«ã 解決ç ïŒ
åé¿ç
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); final Menu m = menu; final MenuItem item = menu.findItem(R.id.your_menu_item); item.getActionView().setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onOptionsItemSelected(item); } }); return true; }
2. MVC / MVP / MVVMãšä»ã®çŸããèšè察ã ã¹ã¯ãªãŒã³ã¹ã€ããã£ãŒ
ç¶æ³
ãããããç§ãã¡äžäººäžäººã¯å°ãªããšãäžåºŠMVCãšãã®èŠªé¡ã«ã€ããŠèããããšããããŸãã MVVMã¯ãŸã Androidäžã«æ§ç¯ã§ããŸããïŒç§ã¯åãã€ããŸããå¯èœã§ããããããŸã§ã®ãšããããŒã¿ç ïŒãã MVCãšMVPãç©æ¥µçã«äœ¿çšãããŠããŸãã ããããã©ã®ããã«ïŒ Androidéçºè ãªã誰ã§ããç»é¢ãå転ããããšã ã¢ã¯ãã£ããã£ãšãã©ã°ã¡ã³ããå®å šã«ç Žå£ãããããšãç¥ã£ãŠããŸãïŒããã«ããããã«å ããŠã»ãã®äžæ¡ãã®ç¥çµãïŒã ããšãã°ã MVPãé©çšãããšåæã«ã Presenterã«å®³ãäžããã«ç»é¢ãå転ãããæ¹æ³ã¯ãããŸããïŒ
解決ç
ãããŠããã§ã«3ã€ã®äž»èŠãªãœãªã¥ãŒã·ã§ã³ããããŸãïŒ
- ã Fragment.setRetainInstanceïŒïŒããã¹ãŠã®å Žæã§äœ¿çšããã°ãããªãã¯å¹žãã«ãªããŸãã-ãŸãã¯ãæ°åè
ã¯éåžžèšãã æ®å¿µãªããããã®ãããªãœãªã¥ãŒã·ã§ã³ã¯ãæåã¯ä¿åãããŸããããã¹ãŠã®èšç»ãç Žæ£ããŸãããå¿
èŠã«å¿ããŠã PresenterãActivityã«è¿œå ããŸãã ãããŠããããèµ·ãããŸãã ã»ãšãã©ã®å Žåã DualPaneãå°å
¥ãããŠããŸã ã
ã©ã®ãããªDualPaneã§ããïŒ
ãŸãã setRetainInstanceïŒïŒã«ã¯ããã®å©ç¹ãæ¯æããªããã°ããããŸãã ããããããã«ã€ããŠã¯åŸã§ã - ã©ã€ãã©ãªããã¬ãŒã ã¯ãŒã¯ãªã©ã 幞ããªããšã«ããããã®ããªãã®æ°ããããŸãïŒ ã¢ã¯ã·ãŒïŒåæ§ã®ãããã¯ã«é¢ããèšäºãèªãå¿ èŠããããŸãïŒ ã ã¢ã¹ã㌠ã ã¢ã«ã¿ã«ãªã©ã ãããã®ããã€ãã¯ããããããã¥ãŒã¹ããŒãã埩å ããããšãããšãåæã«ããªãã®ç¥çµãæããŸãã
- ããŠããã¯ã¬ã€ãžãŒãã³ããã¢ãããŒã-Singletonãäœæãã GetUniqueIdïŒïŒã¡ãœãããæå®ããŸãïŒåŒã³åºãæã«ã€ã³ã¯ãªã¡ã³ãããŠAtomicIntegerå€ãè¿ããŸãïŒã ãã¬ãŒã³ã¿ãŒãäœæãã以åã«åãåã£ãIDãActivity / Fragmentã® ãã³ãã«ã«ä¿åãã ãã¬ãŒã³ã¿ãŒãIDã§ã¢ã¯ã»ã¹ã§ããã·ã³ã°ã«ãã³å
ã«ä¿åããŸã ã ã§ãã ãã¬ãŒã³ã¿ãŒã¯ã©ã€ããµã€ã¯ã«ããç¬ç«ããŠããŸã
ïŒãŸãã ã·ã³ã°ã«ãã³ã«ãããŸã ïŒã onDestroyïŒïŒã§ çºè¡šè ãåé€ããããšãå¿ããªãã§ãã ããïŒ
3.åçä»ãã®TextView
ãããŠããã€ãã®ããã«ãæºã§ã¯ãªãã¢ããã€ã¹ã§ãã
ãã®ãããªããšãããå¿ èŠãããå Žåã¯ã©ãããŸããïŒ
ç¢æã®ã¢ã€ã³ã³
ããªãã®çãããPfïŒ äœã®åé¡ïŒ LinearLayoutãŸãã¯RelativeLayoutã® TextViewããã³ImageView ã-ãã®ã¢ããã€ã¹ã¯ããªãã«ãŽã£ããã§ãã å¥åŠãªããšã«ã TextViewã«ã¯TextView.drawable {ANY_SIDE}ããããã£ãšTextView.drawablePaddingããããŸãã ãããã¯ãæ¬æ¥ããã¹ãããšãæ£ç¢ºã«è¡ãããã¹ããããã¬ã€ã¢ãŠãã¯è¡ããŸããã
TextView.drawable {ANY_SIDE}ãã©ã®ããã«èŠããã
æ£çŽãªãšããã TextViewããç»åã«é¢é£ããããããã£ãæ¢ãããšã¯æ±ºããŠãªãã£ãã®ã§ãç§èªèº«ã¯ãã®ããããã£ã«ã€ããŠæ¯èŒçæè¿ããããŠå¶ç¶ã«ç¥ããŸããã
4. Fragment.setRetainInstanceïŒïŒã䜿çšãããšã ã¢ã¯ãã£ããã£ ïŒ AppCompat ïŒã®çŽæ¥ã®åå«ã®ã¿ãä¿åã§ããŸãã
ç¶æ³
ããªãã®ç¶èŠªããžã§ã³ã»ã¿ã€ã¿ãŒã§ãããããªãã®æ¯èŠªããµã©ã»ã³ããŒã§ãããããªããé ã2013幎ããæ¥ãå Žåãããªãã¯ãŸã åã蟌ãŸãããã©ã°ã¡ã³ãã«å¯Ÿããæãã¿ã®æ°é®®ãªæ°æã¡ãæã£ãŠããŸãã å®éãåœæã圌ãã®ãäžåŸé ãïŒ tyts ã tyts ïŒã«å¯ŸåŠããããšã¯éåžžã«å°é£ã§ãã åã蟌ãŸãããã©ã°ã¡ã³ããå«ãã³ãŒããã¯ããã«ãæŸèæãåããã³ãŒããã«å€ãããŸããã
åœæãç§ã¯ããã°ã©ãã³ã°ãå§ããã°ããã§ããã®ãããªææãèªãã§ããã®ã§ã åã蟌ãŸããæçãæã«å ¥ããªãããšãèªããŸããã
æéãçµã€ã«ã€ããŠãç§ã¯ãã©ã°ã¡ã³ãã®ãã¹ãã䜿çšãããäœããã®çç±ã§ãã®èšç»ã®ãã¹ãŠã®ãã¥ãŒã¹ãéãéããŸãã...ãããŠãçªç¶ã ãã©ã°ã¡ã³ããå®å šã«ãã¹ãããããšãããã¥ãŒã¹ã«ééããŸããïŒãããããªã³ã¯ãsoããŸããïŒäººçå šè¬==ããšã話ã ãããŠãç§ã¯äœãèšãããšãã§ããŸã-ç§ã¯ä¿¡ããŠããŸããïŒ ãããžã§ã¯ããäœæãã ãã©ã°ã¡ã³ãã®ããã·ã¥ ãã¬ãŒã³ã¿ãŒãè²ã«å€æããäŸãããŒã«ã¢ãããïŒããã«ããã ä¿æãæ©èœããŠãããã©ãããããã«å€æã§ããããã«ãªããŸãïŒãèµ·åããç»é¢ãå転ãããŠ...
ãããŠ..ïŒ
ãããŠãé±æ«å šäœãéããŠã第1ã¬ãã«ã®ãã©ã°ã¡ã³ãïŒ ã¢ã¯ãã£ããã£èªäœã«ä¿åãããŠãããã©ã°ã¡ã³ãïŒã®ã¿ãä¿åãããçç±ãæ¢ããŸããã åœç¶ãç§ãæåã«çœªãç¯ãå§ããã®ã¯èªåèªèº«ã§ããã ãã€ã³ãã³ãŒãããå§ãŸãã MVPã®æ²æ» ã§çµããã³ãŒãå šäœã調ã¹ã SDKã®ãœãŒã¹ã調ã¹ã Nested Fragmentsã®å€§éã®æçš¿ãæãäžããŸãã ïŒãããŠãæ®å¿µãªéçºè ã§ãããããããªã¯ã©ãŠãããããŸãïŒããããŠãå é±æ«ã®çµãããŸã§ã«çºèŠããŸããïŒïŒïŒ ãã ïŒ
èªãã®ãé¢åãªäººã®ããã«ïŒ Fragment.setRetainInstanceïŒïŒã¯FragmentManagerã䜿çšããŠFragmentãç Žå£ãããã®ãé²ããŸã-ããã¯ãã¹ãŠå€§äžå€«ã§ãã ããããäœããã®çç±ã§ãéçºè ã®1人ãmFragmentManager = null;ãšããè¡ãè¿œå ããŸããã ãããã³Fragmentå®è£ ã®ã¿-Activityããã¹ãŠåé¡ãªãçç±ã§ãïŒ
ãªãããªãããããŠã©ã®ããã«å€æãããã¯ãæªåçã«ãªãèå³æ·±ã質åã§ãã ãã®1è¡ã®ãã°ã¯2.5ããŒãžã§ã³ã§ãç¶ããŸãã åã®ãªã³ã¯ïŒ æ ãè ã®å Žå ïŒã¯ã ãªãã¬ã¯ã·ã§ã³ã®åé¿çã«ã€ããŠèª¬æããŠããŸãã æ®å¿µãªãããä»ã®ãšãããããåé¡ã解決ããå¯äžã®æ¹æ³ã§ãïŒãã¡ããããœãŒã¹ã³ãŒãããããžã§ã¯ãã«å®å šã«ã³ããŒããããšã¯å¥ãšããŠïŒã åé¡èªäœã¯ã ãã°ãã©ãã«ãŒã§è©³çŽ°ã«èª¬æãããŠããŸãã
psã¿ã€ã ãã·ã³ã売ããªãwonïŒã»_ââ¬âŽâ¬âŽ
5. RxJava ïŒ observeOnïŒïŒãšsubscribeOnïŒïŒã®éã
ãããããç§ã¯æãåçŽãªãã®ã§ãããšåæã«æãéèŠãªãã®ããå§ããŸãã
Rxãèµ·åããã°ããã®ãšãããããã®æ¹æ³ã®éãã¯ç§ã«ã¯å®å šã«äžæçã§ããã è«ççã«ã subscribeOnïŒïŒã¯ã subscribeïŒïŒãåŒã³åºãããã¹ã±ãžã¥ãŒã©ãå€æŽããŸã ã ããã... ...å¥ã®ããžãã¯ã®èŠ³ç¹ã§ã¯ã Subscriberã¯Observerãç¶æ¿ããŸããã Observerã¯äœãããŸããïŒ ãããã芳å¯ãã ã ãããŠããã«èªç¥çäžååé³ããããŸããã ã°ãŒã°ã«ãã ã¹ã¿ãã¯ãªãŒããŒãããŒãã å ¬åŒã®ããŒçã§ãããæå¿«ãããããããŸããã§ããã ãããããã¡ããããã®ãããªç¥èã¯éåžžã«éèŠã§ããã Schedulersã§1é±éãŸãã¯2ã€ã®ãã¹ãç¯ããåŸãããã ãã§çãŸããŸããã
ç§ã¯ããå人ãããã®è³ªåãèããæã«ã¯ããŸããŸãªãã©ãŒã©ã ã§åºããããŸãããã®ãããçµæãå¿é ããã«ããåå¿ãããããŸãã¯ãããã®æŒç®åãåçŽã«çŽæçã«äœ¿çšãã人ã®èª¬æã次ã«ç€ºããŸãã
ã³ãŒã
Observable.just(null) .doOnNext(v0id -> Log.i("TAG", "0")) // : computation .observeOn(Schedulers.newThread()) .doOnNext(v0id -> Log.i("TAG", "1")) // : newThread .observeOn(Schedulers.io()) // io .doOnNext(v0id -> Log.i("TAG", "2")) : io .subscribeOn(Schedulers.computation()) .subscribe(v0id -> Log.i("TAG", "3")); // - : io
ïŒç§èªèº«ã®çµéšããïŒæãçŽããããããšã¯ã ReactiveXãã¹ããŒã¬ã³ããã¹ãŠã¯ã¹ããªãŒã ã§ããã§åé²ããŠããããšã ãšæããŸã ã ãã®çµæãæ°èŠåå ¥è ã¯ãåæŒç®åãããã«ç¶ãæŒç®åã®ã¿ã«åœ±é¿ããã¹ããªãŒã å šäœã«ã¯åœ±é¿ããªãããšãæåŸ ããŠããŸãã ããããããã¯ããã§ã¯ãããŸããã ããšãã°ã startWithïŒïŒã¯ã¹ããªãŒã ã®éå§ã«åœ±é¿ãã finallyDoã¯ã¹ããªãŒã ã®çµäºã«åœ±é¿ããŸãã
RxãœãŒã¹ã³ãŒãã§ã®ååã«ã€ããŠã¯ãããŒã¿ã¯Observableã¯ã©ã¹ã§ã¯ãªãïŒçªç¶ã§ããïŒïŒã OnSubscribeã¯ã©ã¹ã«ãã£ãŠçæãããããšãããããŸãã ãããsubscribeOnïŒïŒæŒç®åã®çŽããããååã®ç±æ¥ã§ãããšæããŸãã
ã¡ãªã¿ã«ã Frodoã®ãã°èšé²ã«æ £ããŠããããã«ãåå¿è ãçµéšè±å¯ãªæ奜家ã§ãã£ãŠã匷ããå§ãããŸã ã Rxã³ãŒãã®åæ¹èšå ¥ã¯äŸç¶ãšããŠäœæ¥ã§ãããããæéãå€§å¹ ã«ç¯çŽããŠãã ããã
6. RxJava ïŒ æŒç®åãšãã©ã³ã¹ãã©ãŒããŒ
ç¶æ³
Rxã³ãŒãã倧ãããªãããšãããããã®ã§ãã©ãã«ãããŠãããæžãããããšæããŸãã ãã§ãŒã³ã®åœ¢ã§ã¡ãœãããåŒã³åºãæ¹æ³ã¯ ãã¯ããè¯ãã§ããããã®åå©çšã¯ãŒãã§ã-ããªãã¯å°ããªããšãªã©ãè¡ããã¹ãŠã®åãã¡ãœãããåŒã³åºãå¿ èŠããããã³ã« ãªã©
ãã®ãããªããŒãºã«çŽé¢ããåå¿è ã¯ãOOPã®èŠ³ç¹ããèãå§ãããã¹ãŠãæ¬åœã«æªãå Žåã¯éçã¡ãœãããäœæããåŒã³åºãã®ãã§ãŒã³ã®å§ãŸããã©ããããŸãã æéå ã«ãã®ã¢ãããŒããå»æ¢ããªããã°ã Observableããšã«3ã4åã®ã©ãããŒã«ãªããŸãã
å®éã®è£œåã®ããããã®å®éã®ã³ãŒã
RxUtils.HandleErrors( RxUtils.FireGlobalEvents( RxUtils.SaveToCaches( Observable.defer(() -> storeApi.getAll(filter)).subscribeOn(Schedulers.io()), caches) , new StoreDataLoadedEvent() ) ).subscribe(storeDataObserver);
å°æ¥çã«ã¯ãããã¯ã³ãŒããäœãããŠããã®ããç解ããã人ãäœããå€æŽããã人ã«å€ãã®åé¡ãããããã§ãããã
ãããŠä»äœïŒ
ãã§ãŒã³ã¡ãœããã¯èªã¿ããããããåªããŠããŸãã ã§ããã ãæ©ãç¬èªã®æŒç®åãšãã©ã³ã¹ãäœæããæ¹æ³ãåŠã¶ããšããå§ãããŸãã æã£ãããç°¡åã§ãã Operatorã¯ããŒã¿ãŠãããïŒããšãã°ã onNextïŒïŒãäžåºŠã«1ååŒã³åºãïŒã§åäœãã Transformerã¯Observableèªäœãå€æããããšãç解ããããšãéèŠã§ãïŒããã§ã¯ãéåžžã®mapïŒïŒ/ doOnNextïŒïŒãªã©ã1ã€ã®å šäœã«çµåã§ããŸãïŒã
ãã¹ãŠåäŸåãã®ã²ãŒã ã§çµäºããŸããã æºã«ç§»ããŸãããã
7. RxJava ïŒ ãµãã¹ã¯ãªãã·ã§ã³ã®å®è£ ã«ãããã«ãªã¹
ç¶æ³
ã ãããããªãã¯åå¿çã§ãïŒ ããªãã¯ãããè©ŠããŠã¿ãŸãããããªãã¯ããã奜ãã§ãããããªãã¯ãã£ãšæ¬²ããã§ãïŒ Rxã§ãã¹ãŠã®ãã¹ãé ç®ããã§ã«æžããŸããã Rxã§ããŒã ãããžã§ã¯ããæžãæããŠããŸãã Rxã«ããªãã®ç«ãæããŸãã ãããŠä»ãGrailãäœæãããšããããŸãããRxã§ã¢ãŒããã¯ãã£å šäœãæ§ç¯ããããã§ãã ããªãã¯æºåãã§ããŠããŸããããªãã¯é »ç¹ã«ããããŠã ãããªãããã«åŒåžãããããŠ...å§ããŸã...
ãªãã§ïŒ
æ®å¿µãªãããäžèšã¯ç§ã®ããã§ãã Rxã®ãã¯ãŒã«éåžžã«é©ããã®ã§ãã¢ãŒããã¯ãã£ãæžãããã®ãã¹ãŠã®ã¢ãããŒããå®å šã«åèããããšã«ããŸããã MVP + Rxã䜿çšããŠMVVMãåçºæããããšãããšèšããŸãã
ãã ããåå¿è ã®æ倧ã®ééãã¯èªããŸããRxãç解ãããšå€æããŸããã
ãããããç解ããã«ã¯ãããã€ãã®Rxã¢ããªã±ãŒã·ã§ã³ãæžãã ãã§ã¯äžååã§ã ã ã¯ãªãã¯ãšãžã£ã³ãã3ã€ã®ç°ãªããœãŒã¹ããã®åçããããªããã¹ãããŒã¿ã«ãªã³ã¯ãããããã¿ã¹ã¯ãè€éã«ãªããšã ããã¯ãã¬ãã·ã£ãŒãªã©ã®çªç¶ã®åé¡ãçºçããŸãã ãããŠã èå§ãç¥ã£ãŠãããšæ±ºãããšãããªãã¯Producerã«ã€ããŠäœãç¥ããªãããšã«æ°ä»ãã§ãããïŒéåžžã®ããã¥ã¡ã³ãããããããŸããïŒ...äœãç§ã¯éžããŸãïŒãããŠèšäºã®çµããã«ãããã¯ãªãæããã«ãªããŸãïŒã
äžè¬ã«ãåé¡ã®æ¬è³ªã¯ããžãã¯ã«ãããå®éã«å©çšå¯èœãªãã®ãšã¯éã«ãªããŸãã
ãªã¹ãã³ã°ã¯éåžžã©ãã§ããïŒ
//... data.registerListener(listener); // data.mListener == listener //... data.unregisterListener(); // data.mListener == null
ã€ãŸããããŒã¿ãœãŒã¹ã«ã¯ãªã¹ããŒãžã®åç §ãæ ŒçŽãããŸãã
ããããRxã§ã¯ã©ããªããŸããïŒ ïŒæ éã«ãä»ã§ã¯æçã¯
observer.unsubscribeïŒïŒ 500ããªç§ã§
ã³ãŒã
Observable.interval(300, TimeUnit.MILLISECONDS).map(i -> "t1-" + i).subscribe(observer); l("interval-1"); Observable.interval(330, TimeUnit.MILLISECONDS).map(i -> "t2-" + i).subscribe(observer); l("interval-2"); Observable.timer(500, TimeUnit.MILLISECONDS).map(i -> "t3-" + i).subscribe(ignored -> observer.unsubscribe());
çµæ
interval-1 interval-2 t1-0 t2-0
ãããæãæåŸ ãããçµæã ãšæããŸãã ãããã¹ãŠãšãã¹ãŠãåäœæããæ¹æ³ïŒã
500msã§subscription1.unsubscribeïŒïŒ
次ã«ã Subscriberããã§ã¯ãªãã Subscriptionãããµãã¹ã¯ã©ã€ãã解é€ããŠã¿ãŸãããã è«ççãªèŠ³ç¹ããã ãµãã¹ã¯ãªãã·ã§ã³ã¯ObserverãšObservableã1ïŒ1ãšããŠãã€ã³ãããäœãããéžæçã«ãµãã¹ã¯ãªãã·ã§ã³ã解é€ã§ããããã«ããå¿ èŠããããŸããã...
ã³ãŒã
Subscription subscription1 = Observable.interval(300, TimeUnit.MILLISECONDS).map(i -> "t1-" + i).subscribe(observer); l("interval-1"); Observable.interval(330, TimeUnit.MILLISECONDS).map(i -> "t2-" + i).subscribe(observer); l("interval-2"); Observable.timer(500, TimeUnit.MILLISECONDS).map(i -> "t3-" + i).subscribe(ignored -> subscription1.unsubscribe());
çµæ
interval-1 interval-2 t1-0 t2-0
...çªç¶ãçµæã¯ãŸã£ããåãã«ãªããŸãã RxãåããŠç¥ã£ããšããããã«ã€ããŠã¯ç¥ããŸããã§ãããããããããŸããããšæã£ãŠé·ãéåããããªã¢ãããŒãã䜿çšããŠããŸããã å®éã«ã¯ã Subscriberã¯Observerã€ã³ã¿ãŒãã§ã€ã¹ãš... Subscriptionãå®è£ ããŠããŸãã ã€ãŸã ç§ãã¡ãæã£ãŠãããµãã¹ã¯ãªãã·ã§ã³ã¯åããªãã¶ãŒããŒã§ãïŒ ããã«ãã®ãããªã¿ãŒã³ããããŸãã
Observable.deferïŒïŒããã³Observable.fromCallableïŒïŒ
deferïŒïŒã¯ã Rx ïŒ Observable.flatMapïŒïŒãšåçïŒã§æããã䜿çšãããæŒç®åã®1ã€ã ãšæããŸãã ãã®ã¿ã¹ã¯ã¯ã subscribeïŒïŒãåŒã³åºããããŸã§ObservableããŒã¿ã®åæåã延æããããšã§ãã è©ŠããŠã¿ãŸãããïŒ
ã³ãŒã
Observable.defer(() -> Observable.just("s1")).subscribe(observer); l("just-1"); Observable.defer(() -> Observable.just("s2")).subscribe(observer); l("just-2"); observer.unsubscribe(); Observable.defer(() -> Observable.just("s3")).subscribe(observer); l("just-3");
çµæ
s1 just-1 s2 just-2 s3 just-3
ããããŠäœïŒ äºæããªãããšã¯ãããŸããããšããªãã¯èšããŸãã ãããããããšçããŸãã
ãããã Observable.justïŒïŒã®äœæã«ããããããŠããå Žåã¯ã©ãã§ããããïŒ Rxã«ã¯çãããããŸãã ã°ãŒã°ã«ã§ç°¡åã«æ€çŽ¢ãããšã Observable.fromCallableïŒïŒã¡ãœãããèŠã€ãããŸããããã«ããã Observableã§ã¯ãªãéåžžã®ã©ã ãã延æã§ããŸãã ç§éã¯è©Šã¿ãŸãïŒ
ã³ãŒã
Observable.fromCallable(() -> "z1").subscribe(observer); l("callable-1"); Observable.fromCallable(() -> "z2").subscribe(observer); l("callable-2"); observer.unsubscribe(); Observable.fromCallable(() -> "z3").subscribe(observer); l("callable-3");
çµæïŒæ³šæïŒç»é¢ããåäŸãšãã ã¹ã¿ãŒãåé€ããŸãïŒ
z1 callable-1 callable-2 callable-3
ç°ãªããœãŒã¹ããŒã¿ã§ã®ã¿åãããšãããã¡ãœããã§ããããã®ãããªéããããããã«æãããŸãã ãã®çµæã§æããããã«ããïŒè«ççã«èãããšïŒã®ã¯ã z1-z2-callableã§ã¯ãªãããšã§ã ïŒãããŸã§ã«èª¬æãããã¹ãŠãä¿¡ããŠããå ŽåïŒãã€ãŸãã z1-callable ...ã§ãã åé¡ã¯äœã§ããïŒ
äºå®ã¯...
ãããŸã§ããã€ã³ãã§ãã å®éãå€ãã®æŒç®åã¯ããŸããŸãªæ¹æ³ã§èšè¿°ãããŠããŸãã 次ã®onNextïŒïŒã®åã®èª°ããSubscriberãµãã¹ã¯ãªãã·ã§ã³ããã§ãã¯ãã誰ããçºè¡åŸã«ãã§ãã¯ããŸãããæåŸã®onNextïŒïŒãŸã§ããããŠèª°ããååŸã«ãã§ãã¯ããŸãã ããã«ãããäºæ³ãããçµæã«æ··ä¹±ãçããŸãã ããããããã§ãObservable.fromCallableïŒïŒã®åäœã説æããŠããŸããã
Rxå ã«ã¯ã SafeSubscriberã¯ã©ã¹ããããŸãã ããã¯ãŸãã«ãã¡ã€ã³ã®Rxã³ã³ãã©ã¯ããæ åœããã¯ã©ã¹ã§ãïŒã onErrorïŒïŒã®åŸã onNextïŒïŒã¯ãªããªãã ãµãã¹ã¯ãªãã·ã§ã³è§£é€ãªã©ãçºçããããªã©ïŒã ãããŠãããããªãã¬ãŒã¿ãŒã§äœ¿çšããå¿ èŠããããïŒ SafeSubscriber ïŒãã¯ãã©ãã«ãç»é²ãããŠããŸããã äžè¬ã«ã Observable.fromCallableïŒïŒã¯éåžžã®subscribe ïŒïŒãåŒã³åºããŸãããããã£ãŠã SafeSubscriberã¯æé»çã«äœæããã çºè¡åŸã«unsubscribe ïŒïŒãçºçããŸããã Observable.deferïŒïŒã¯unsafeSubscribeïŒïŒãåŒã³åºããŸãã ãããã£ãŠãå®éã«ã¯ïŒçªç¶ïŒïŒãã®Observable.deferïŒïŒã¯æªããã®ã§ããã Observable.fromCallableïŒïŒã§ã¯ãããŸããã
8. RxJava ïŒæåã§ã®ãµãã¹ã¯ã©ã€ã解é€/ãµãã¹ã¯ã©ã€ãã®ä»£ããã«repeatWhenïŒïŒ
ç¶æ³
Xç§ããšã«ããŒã¿ãæŽæ°ããå¿ èŠããããŸãã ãã¡ãããå€ãããŒã¿ãããŠã³ããŒããããŸã§ãæ°ããããŒã¿ãããŠã³ããŒãããããšã¯ã§ããŸããïŒããã¯ãã©ã°ããã°ãããã³ãã®ä»ã®äžæ£ã®ããã«å¯èœã§ãïŒã ã©ããã
ãããŠããã¹ãŠãå¿çããŠå§ãŸããŸãïŒ Observable.interttleïŒïŒãšObservable.throttleïŒïŒãŸãã¯AtomicBoolean ããããŠäžéšã¯æåunsubscribe ïŒïŒãä»ããŠãããè¡ãããšããã§ããŸãã å®éããã¹ãŠãã¯ããã«åçŽã§ãã
解決ç
Rxã«ã¯ãã¹ãŠã®å Žåã«æŒç®åãããããã§ãã ã ããä»ã§ãã ããªãã®ããã«ãã¹ãŠãè¡ãrepeatWhenïŒïŒã¡ãœããããããŸã-æå®ãããééã§Observableã«åãµãã¹ã¯ã©ã€ãããŸãïŒ
RepeatWhenïŒïŒã®äŸ
Log.i("MY_TAG", "Loading data"); Observable.defer(() -> api.loadData())) .doOnNext(data -> view.setDataWithNotify(data)) .repeatWhen(completed -> completed.delay(7_777, TimeUnit.MILLISECONDS)) .subscribe( data -> Log.i("MY_TAG", "Data loaded"), e -> {}, v0id -> Log.i("MY_TAG", "Loading data")); // "Loading data" - ; "Data loaded" - ~8 .
å¯äžã®ãã€ãã¹ç¹ã¯ãæåã¯ãã®æ¹æ³ãã©ã®ããã«æ©èœããããå®å šã«æ確ã§ã¯ãªãããšã§ãã ãããããã€ãã®ããã«ã repeatWhenïŒïŒ/ retryWhenïŒïŒã«é¢ããè¯ãèšäºããããŸãã
åè©Šè¡ãããšã
ã¡ãªã¿ã«ã repeatWhenïŒïŒã®ã»ãã«ãåãããšãããretryWhenïŒïŒããããŸããã onErrorïŒïŒã®ããã§ãã ãã ãã repeatWhenïŒïŒãšã¯ç°ãªãã retryWhenïŒïŒã圹ç«ã€ç¶æ³ã¯éåžžã«å ·äœçã§ãã äžèšã®å Žåãããããè¿œå ããããšãã§ããŸãã ãã ããäžè¬çã«ã¯ã Rx Plugins / Hooksã䜿çšããŠãç®çã®ãšã©ãŒã®ããã«ã°ããŒãã«ãã³ãã©ãŒããã³ã°ãããæ¹ãé©åã§ãã ããã«ããããšã©ãŒãçºçããå Žåã«Observableãåãµãã¹ã¯ã©ã€ãã§ããã ãã§ãªãããŠãŒã¶ãŒã«éç¥ããããšãã§ããŸãïŒããšãã°ã SocketTimeoutExceptionã«äŒŒããããªãã®ã䜿çšããŸãïŒã
è¿œå ã RxJava ïŒ16
ãããŠæåŸã«ããããç§ããã¥ãããã«ã€ããŠæžãå§ããçç±ã§ãã ç§ã人çã®2é±éãè²»ãããããã©ã®ãããª...éæ³ãããã«èµ·ãã£ãŠããã®ããŸã ããããªããšããåé¡...ããããé çªã«èŠãŠã¿ãŸãããã
ç¶æ³
èªèšŒç»é¢ãäœæãã誀ã£ãŠå ¥åããããã£ãŒã«ãããã§ãã¯ãã3çªç®ã®ãšã©ãŒããšã«ç¹å¥ãªèŠåãçºè¡ããå¿ èŠããããŸãã
ã¿ã¹ã¯èªäœã¯é£ãããªãããã Rxã® ããã¹ããµã€ãããšããŠéžæããŸããã ãµãŒããŒããããŒã¿ãããŠã³ããŒãããã ãã®ããžãã¹ãšã¯ç°ãªãããžãã¹ã§Rxãã©ã®ããã«åäœããã®ãã確èªããŸãã
ãã®ãããã³ãŒãã¯æ¬¡ã®ããã«ãªããŸããã
ãã°ã€ã³ãšã©ãŒåŠçã³ãŒã
PublishSubject<String> wrongPasswordSubject = PublishSubject.create(); /*...*/ wrongPasswordSubject .compose(IndexingTransformer.Create()) .map(indexed -> String.format(((indexed.index % 3 == 0) ? "GREAT ERROR" : "Simple error") + " #%d : %s", indexed.index, indexed.value)) .observeOn(AndroidSchedulers.mainThread()) .subscribe(message -> getView().setMessage(message));
ãã¿ã³åŠçã³ãŒã[ãµã€ã³ã€ã³]
private void setSignInAction() { getView().getSignInButtonObservable() .observeOn(AndroidSchedulers.mainThread()) .doOnNext((v) -> getView().setSigningInState()) // .observeOn(Schedulers.newThread()) .withLatestFrom(formDataSubject, (v, formData) -> formData) .map(formData -> auth(formData.login, formData.password)) // . WrongLoginOrPassException .lift(new SuppressErrorOperator<>(throwable -> wrongPasswordSubject.onNext(throwable.getMessage()))) // .compose(new UnObservableTransformer<>()) // flatMap(). .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> getView().setSignedInState(user)); // happy end }
ç§ãã¡ã¯ã Rxã¹ã¿ã€ã«ã®ã³ãŒãã«å¯Ÿãã䞻匵ã延æããŸãããã¹ãŠãæªããç§ã¯ãããèªåã§ç¥ã£ãŠããŸãã ããã¯ããã§ã¯ãªãããã£ãšåã«æžãããŸããã
ãããã£ãŠã getViewïŒïŒãGetSignInButtonObservableïŒïŒã¯ã [Sign In]ãã¿ã³ãã¯ãªãã¯ãããšãã«RxAndroidããåä¿¡ããObservableãè¿ããŸãã ããã¯æ³šç®ã«å€ãããã®ã§ã ãã€ãŸãã å®äºããããšã¯ã§ããŸããã ã€ãã³ãã¯ããããå§ãŸãã ãããïŒïŒãééããŸããããã§èªèšŒãè¡ãããããã«ãã§ãŒã³ã«æ²¿ã£ãŠé²ã¿ãŸãã ãšã©ãŒãçºçããå Žåãã«ã¹ã¿ã ãªãã¬ãŒã¿ãŒã¯ãšã©ãŒããã£ãããããã以äžèŠéããŸããã
SuppressErrorOperator
public final class SuppressErrorOperator<T> implements Observable.Operator<T, T> { final Action1<Throwable> errorHandler; public SuppressErrorOperator(Action1<Throwable> errorHandler) { this.errorHandler = errorHandler; } @Override public Subscriber<? super T> call(final Subscriber<? super T> subscriber) { return new Subscriber<T>(subscriber) { @Override public void onCompleted() { subscriber.onCompleted(); } @Override public void onError(Throwable e) { errorHandler.call(e); // , } @Override public void onNext(T t) { subscriber.onNext(t); } }; } }
ã ããåé¡ã¯ã ãã®ã³ãŒãã®äœãåé¡ã«ãªã£ãŠããŸããïŒ
圌ããããã«ã€ããŠç§ã«å°ããããç§ã¯ä»ã§ãçããŸãïŒããã¹ãŠã¯å€§äžå€«ã§ããã Subscriptionãä¿åããå Žæããªããããã¡ã¢ãªãªãŒã¯ãé€ããŸãã ã¯ãã onNextã®ã¿ãsubscribeã§äžæžããããŸãããä»ã®ã¡ãœããã¯åŒã³åºãããŸããã ãã¹ãŠé 調ã§ããç§ãã¡ã¯åãçµãã§ããŸãã
çã¿
ãã¯ã¿ã€
ãããŠãããããæãå¥åŠãªããšãå§ãŸããŸãã ã³ãŒãã¯æ¬åœã«æ©èœããŸãã ããããç§ã¯çŽ°å¿ã®æ³šæãæã£ãŠããã®ã§ãæ¿èªãã¿ã³ãã¯ãªãã¯ããããšã«ããŸãã...äœåºŠãã ãããŠãçªç¶ã5çªç®ã® "GREAT ERROR"ã®åŸãäœããã®çç±ã§èªèšŒã®é²è¡ç¶æ³ããŒïŒ setSigningInStateïŒïŒã§èšå®ïŒãæ©èœããªãã£ãããšãçºèŠããŸããïŒãã®æ©èœã¯[ãµã€ã³ã€ã³]ãã¿ã³ããªãã«ããŸãïŒã
ãããŒãããšæãã UIãæ åœããFragmentã®é¢æ°ãå確èªããŸããïŒçªç¶ãäœããæ¿å ¥ãããŸããïŒã authïŒïŒé¢æ°ã確èªããŸããããã¹ãã®ã¿ã€ã ã¢ãŠããèšå®ããŠããå¯èœæ§ããããŸãã ãã 倧äžå€«ã§ãã
ãããããç§ã¯ããããããŒã®ã¬ãŒã¹ã§ãããšæ±ºããŸããã ç§ã¯ãããåã³éå§ããããäžåºŠãã§ãã¯ããŸãã...ãŸãã«5ãGREAT ERRORããšç¡éã®ããã°ã¬ã¹ããŒã®åæ»ã ãããŠç·åŒµããã åã³èµ·åãããã®åŸãŸããŸãã ãŸãã«5ïŒ 5çªç®ã®ãGREAT ERRORãã®çŽåŸã«ããã¿ã³ãæŒããŠãåå¿ããªããªããšãé²è¡ç¶æ³ããŒãå転ããŠç¡é³ã«ãªããŸãã
ãããããŸããããã setSigningInStateïŒïŒãåé€ããŸããã Androidã¯äººãšéã¶ã®ã倧奜ãã§ãã çªç¶ã SDKã®äœããå£ããŸãããå¯äžã®ããšã¯ããã¿ã³ãããäžåºŠã¯ãªãã¯ããããšãã§ããããã®ãã³ãã©ãŒãæ©èœããªãããšã ãã§ã¯ãããŸãããã ãã å©ãã«ã¯ãªããŸããã§ããã
ãã®ç¬éãŸã§ã«ãç§ã¯ãã§ã«éåžžã«ç·åŒµããŠããŸããã LogCatã¯ç©ºã§ããšã©ãŒã¯ãªããã¢ããªã±ãŒã·ã§ã³ã¯åäœããŠããããã³ã°ããŠããŸããã§ããã ãã³ãã©ãŒã¯ããåŠçããŸããã
åæ
ã¿ã¹ã¯èªäœãç§ã欺ããããšãå€æããŸããã ãGREAT ERRORãã®æ°ãæ°ããŸããããå®éã«ã¯ãã¿ã³ãæŒããæ°ãæ°ããªããã°ãªããŸããã§ããã æ£ç¢ºã«16ãæ°å€ã¯å€æŽãããŸããããç¶æ³ã¯å€ãããŸããã
ãããã£ãŠãäžèŠãªãã®ããã¹ãŠåé€ããåŸã®æ¬¡ã®è©Šã¿ã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
doOnNextïŒïŒã«ãã°ãããã³ãŒã
private void setSignInAction() { getView().getSignInButtonObservable() .observeOn(AndroidSchedulers.mainThread()) .doOnNext((v) -> l("1")) .observeOn(Schedulers.newThread()) .doOnNext((v) -> l("2")) .map(v -> { throw new RuntimeException(); }) .lift(new SuppressErrorOperator<>(throwable -> wrongPasswordSubject.onNext(throwable.getMessage()))) .doOnNext((v) -> l("3")) .observeOn(AndroidSchedulers.mainThread()) .doOnNext((v) -> l("4")) .subscribe(user -> runOnView(view -> view.setTextString("ON NEXT"))); }
ãããŠãç¶æ³ã¯ããã«å¥åŠã«ãªããŸããã 1ã15åã®ã¯ãªãã¯ãæ£åžžã«è¡ãããæ°åã®ã1ããšã2ãã衚瀺ãããŸãããã16åç®ã®ãã°ã®æåŸã®è¡ã¯ã1ãã§ããã ãšã©ãŒãžã§ãã¬ãŒã¿ãŒã«å°éããŸããã§ããïŒ
ãã ãããããã¯äŸå€ã«é¢ãããã®ã§ã¯ãªãã®ã§ããããïŒïŒããšæããŸããã throw new RuntimeExceptionïŒïŒãreturn nullããã³...ã§çœ®ãæãããã¹ãŠãæ©èœããã¯ãªãã¯ããåæ°ã«é¢ä¿ãªã4æ¡ãã¹ãŠã衚瀺ãããŸãïŒãã¹ãŠãããªãŒãºããããšãæåŸ ããŠ100å以äžã¯ãªãã¯ããŸãããããããïŒã
ãã®ç¬éãŸã§ã«ã2æ¥ç®ãŸãã¯3æ¥ç®ã¯ãã§ã«ç§ã®èŠçãšãã®æãŸã§ã«æã£ãŠãããã¹ãŠã®ããšã§ããïŒ
- 16
- Exception
- - doOnNext() «2», Exception
âŠ
æ¥é±ãç§ã¯å®å šã«æããããæ¢ãããã«ReactiveXã®å ¬åŒãŠã§ããµã€ãã調ã¹ãŸãããç§ã¯githubã®RxJavaãªããžããªããŸãã¯ãã®wiki ã調ã¹ãŸãããããŸã çããèŠã€ãããªãã£ããããå¿ æ»ã®ã¹ãããã«æ±ºãã...ãpokeã¡ãœãããã䜿ãå§ããŸããã
ã§ããéãã®ããšãè©ŠããŠã¿ãŠãæçµçã«åé¡ã解決ãããã®ãèŠã€ããŸããïŒonBackpressureBufferïŒïŒãäœãèå§ã«èª¬æãŠã£ãRxJava'vskogoãªããžããªã¯ããšç§ãèšã£ãããã«ãããã¯ç§ããæ€çŽ¢æã«èªã¿åãããŠããŸããããéæ³ã¯ãŸã éæ³ã§æ®ã£ãŠããŸããã
ç¥ããªã人ã®ããã«ãèå§åé¡ãªãã¬ãŒã¿ãŒãåã®ãªãã¬ãŒã¿ãŒããã®ããŒã¿ãåŠçããæéããªããšãã«çºçããŸããæãé¡èãªäŸã¯zipïŒïŒã§ãããŸãããªãã¬ãŒã¿ã¯ããã®èŠçŽ 1æ¯ã«çæããå Žååãããã³ç§-ããã1æéç§ã次ã«ãžãããŒïŒïŒãå±æ²ããããonBackpressureBufferïŒïŒ -æŒç®åã«ãã£ãŠçæãããå šæéã®ãã¹ãŠã®å€ãæ ŒçŽããé åãæé»çã«å ¥åããŸãããããã£ãŠãzipïŒïŒã¯æå³ãããšããã«åäœããŸãïŒãã ããæçµçã«OutOfMemoryExceptionãååŸããŸãïŒã
ãããã質åã«å¿ããŠããªãonBackpressureBufferïŒïŒã圹ç«ã£ãã®ã§ããããïŒç§ã¯äž¡æ¹ã®æ¹æ³ã§ããã°ã©ã ãå®è¡ããŸãããç§ãã¿ã€ããŒãã¯ãªãã¯ããŠã¿ãŸãã[ãµã€ã³ã€ã³] 1åã«1åã ãã§ãïŒãŸããæ°ã«ããªãã§ãã ãããçªç¶Flashã«ãªããã¯ãªãã¯ãéãããŸããïŒïŒããã¡ãããããã¯åœ¹ã«ç«ã¡ãŸããã§ããã
ãã¡ã€ãã«
ããã§ãçµå±ãobserveOnïŒïŒã®æç¹ã§ã³ãŒããæ»ãã§ããããšã«æ°ä»ããŸããã ããããŠãããã¯ã©ã¡ãåŽã§ããïŒããšããªãã¯å°ããŸãã ã¯\ _ïŒãïŒ_ /¯ã-çããŸãã
ãã®ã³ãŒããã³ãŒãonBackpressureBufferïŒïŒããã³Observableæ§é å šäœãç 究ããã®ã«å€ãã®æéãããããŸããããããããOnSubscribeã¯ã©ã¹ãProducerããã®ä»ã®èå³æ·±ãããšãåŠã³ãŸãã...ããããããã ãã§ã¯æããããåŸãããŸããã§ãããRxã®ãœãŒã¹ãå®å šã«ææ¡ãããšèšã£ãŠããããã§ã¯ãããŸããããããããã¯ããŸãã«ãã¯ãŒã«ã§ãããã§ããéã-圹ã«ç«ãããããã«æ·±ãæãã®ã¯æ¬åœã«ç°¡åã§ã¯ãããŸããã
ãã¡ãããç§ã¯stackoverflowã«é¢ãã質åãããŸããããè¿äºã¯ãããŸããã§ããã
onBackpressureBufferïŒïŒãéåžžã«è¿ éã«çºèŠãããšããäºå®ã«ããããããããã®æºã«ã¯çŽ2é±éããããŸããïŒããããåé¡ã®åå ãç解ããã«ã誰ãåé¡ã解決ãããã®ã䜿çšããŸããïŒïŒã
ããªãã®çŸåšã®çµéšã䜿çšããŠãä»®å®ããŸãïŒïŒobserveOnãçæãããµãã¹ã¯ã©ã€ã -obortkuäžã§ãç§ã®å å ¥è ãšããå ŽåãããException'yã¯ã圌ããã©ãããŒã«èç©ããïŒå¥çŽã®ããã«äŸå€ã ãã16ååšããããšãäºæ³ãããªãããã«ããããšãã1ã§ãªããã°ãªããŸããïŒã 17åç®ã®ã¯ãªãã¯ãçºçãããšãobserveOnïŒïŒã¯isUnsubscribedïŒïŒããã§ãã¯ããããã¯ãŸã ããçã誰ãå ¥ããŸããã ïŒããããããã¯ç§ã®æšæž¬ã§ãïŒã
ããžãã¯ãã³ããŒ16ã«ã€ããŠ-äžå®ã®å€§ããã§ããèå§ãããã¡çšAndroid'aãéåžžã®Javaã®å Žåã 128ã§ããããããããã®ãšã©ãŒã«ã€ããŠç§ã¯æ±ºããŠç¥ããªãã§ããããæ°åã®16ãã¢ã¬ã€ã®ãµã€ãºã«é¢ä¿ããŠããå¯èœæ§ãé«ããšæšæž¬ãã䟡å€ããããŸããããç§ã¯æ°åã®5ããå§ããã®ã§ããŸã£ããèããŠããŸããã§ãããçªå·16ãžã®ç§»è¡æãŸã§ã«ã2 + 2 = 17ã§ããããšã¯ãã§ã«ç¢ºä¿¡ããŠããŸããã
ãããŠãæãéæ³ãè¿œå ããæåŸã®ãã®ã¯SuppressErrorOperatorã§ããæåã«ãšã©ãŒãç¡èŠãããªãã£ãå Žåãããã«MissingBackpressureExceptionã«æ°ä»ãã§ããããããŠãã®æ¹åã«çåã«æããŸãããæ°æ¥ç¯çŽã§ããŸããå®éã«ã¯ããŸã å¥åŠãªããšãæ®ã£ãŠããŸãããSuppressErrorOperatorã¯MissingBackpressureExceptionãå«ããã¹ãŠã®ãšã©ãŒãåžåããã¯ãã§ãããªããªããªãã¬ãŒã¿ãŒã¯ãšã©ãŒã®ã¿ã€ãããã§ãã¯ããªãã£ãããããã¹ãŠãåäœãç¶ããã¯ãã§ãïŒ16åç®ã®è©Šè¡[ãµã€ã³ã€ã³]ã®åŸãåŸç¶ã®ãã¹ãŠãåžžã«ç¡é§ã«ãªãããšãé€ãïŒã
ãããã«
ãããã£ãŠãã·ãªãŒãºã®æåŸã®éšåã¯çµäºããŸãããæ¹å€ã«ãããããããå®éãç§ã¯Rxã®ã€ãã£ãªã ãéåžžã«å¥œãã§ã-äžåºŠè©Šè¬ãè©ŠããŠã¿ãããããŒããŒããã®ä»ãšã¯äœã®é¢ä¿ããããŸããã Netflixã®ã¡ã³ããŒã¯ããã§ããŠããŸãã
ãã ããRxã«ã¯æ¬ ç¹ããããŸããããã¥ãŒããã®ã¯é£ãããäžéšã®æŒç®åã¯äºæž¬ã§ããªãçµæããããããŸãããããã®åé¡ã説æãã䟡å€ã¯ãªããšæããŸã-èšäºã®ããã¢ã¯ããã«ã€ããŠã§ããããããç§ã¯äœããèšããŸãã Rxã¯èå³æ·±ããææŠçãªãã®ã§ãã Rxè³ã«ã¯å€ãã®çšåºŠããããŸããããã¯ãå°ããªã¢ã¯ã·ã§ã³ã«ã®ã¿äœ¿çšã§ããŸãïŒããšãã°ãRetrofitåŒã³åºãã®çµæãšããŠïŒïŒããã ããRxã§ã¢ãŒããã¯ãã£å šäœãæ§ç¯ããå·Šå³ã®è€éãªæŒç®åã䜿çšããããå€æ°ã®ãµãã¹ã¯ãªãã·ã§ã³ãç£èŠãããããããšãã§ããŸãã ïŒãã€ãŠãProducerã§Backpressureã䜿çšããŠç»é¢ãåãæ¿ããåŸãView Stateã埩å ããã³ãã³ãã®ãã¥ãŒãäœæããããšããŸããããããè©Šããªãããšããå§ãããŸãã匷ãïŒãäžè¬ã«ãç¡çãããªããšéåžžã«ã¯ãŒã«ã«ãªããŸãã
Rxã®ããã®æ å ±æºãæ¢ããŠãã人ã®ããã«ãããè¯ããããäœããããŸããïŒãã¹ãŠã®äºæ¥è ãšã®å ¬åŒãŠã§ããµã€ãïŒCtrlããŒ+ Fãä»ããªãã«ã¯ãããã€ãã«ã€ããŠã®ãã¹ãŠãç¥ã£ãŠããã¹ãã£ã³ïŒãRxJava github'eäžã®wikiã®æãåå¿è ã®ããã®ãããã³ïŒ ïŒãªã³ã©ã€ã³ãªãã¬ãŒã¿ãŒã®ã€ã³ã¿ã©ã¯ãã£ããªäŸã
psãããŠãããããªãã誰ããæåŸã®ãã¥ãããã§ã©ããªéæ³ãèµ·ãã£ãŠãããç¥ã£ãŠãããªã-ããªãã¯ã³ã¡ã³ããPMããŸãã¯ä»ã®å Žæã§æè¿ãããŠããŸãã幎æ«å¹Žå§ããã詳现ãç¥ã£ãŠããããã§ãã
UPDïŒçªç¶ã®çŽ16 stackoverflowã®äžã®è³ªå蚪ãakarnokdïŒã¡ã€ã³kontribyuterovã®1 RxJavaåœç¶ã§è¿°ã¹ãããã«ãartemgapchenkoïŒãçç±ã¯ãobservonOnïŒïŒ decople'itæŒç®åãããèªäœã®ååŸã«ãããããã¯ãã¬ãã·ã£ãŒãããã¡ãŒãšããŠæ©èœããããã§ãããªããªãäŸå€ãçºçããå ŽåãrequestïŒïŒãåŒã³åºãããããŒã¿ãåã«ã飲ã¿èŸŒããã ãã§ãobserveOnïŒïŒã¯æåã«èŠæ±ããããã®ã ããã€ãŸãå®æ°16ãè¿ããŸããonBackpressureBufferïŒïŒã¯ãæåã«Long.MAX_VALUEãèŠæ±ãããããåé¡ã解決ããŸããAkarnokdããã®å ã®åçã