Kotlinã®ã³ã«ãŒãã³ã«é¢ããã¬ããŒããèªãã§èŠãã°èŠãã»ã©ããã®èšèªããŒã«ãè³è³ããŸããã 圌ãã®å®å®çãªãªãŒã¹ã¯æè¿Kotlin 1.3ã§ãªãªãŒã¹ãããŸãããã€ãŸããäŸãšããŠæ¢åã®RxJavaã³ãŒãã䜿çšããŠããã€ããéå§ããã³ã«ãŒãã³ãå®éã«è©ŠããŠã¿ãŸãããã ãã®æçš¿ã§ã¯ãRxJavaãã³ã«ãŒãã³ã«çœ®ãæããããšã«ãããæ¢åã®ãããã¯ãŒã¯èŠæ±ãååŸããŠå€æããæ¹æ³ã«çŠç¹ãåœãŠãŸãã
ççŽã«èšã£ãŠãã³ã«ãŒãã³ãè©Šãåã¯ã以åãšã¯ãŸã£ããéããšæããŸããã ãã ããcorutinã®åºæ¬ååã«ã¯ãRxJavaãªã¢ã¯ãã£ããããŒã§äœ¿çšããããã®ãšåãæŠå¿µãå«ãŸããŠããŸãã äŸãšããŠãåçŽãªRxJavaæ§æã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ã®1ã€ãããããã¯ãŒã¯èŠæ±ãäœæããŸãããã
- Rxã¢ããã¿ãŒïŒ retrofit2ïŒadapter-rxjava2 ïŒã䜿çšããŠã Retrofitã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ããŸãã é¢æ°ã¯ã SingleãObservableãªã©ã®Rxãã¬ãŒã ã¯ãŒã¯ãããªããžã§ã¯ããè¿ããŸãã ïŒå€ãã³ãŒããKotlinã§äœæãããŠãããšæ³å®ãããŠãããããã¡ãœããã§ã¯ãªãé¢æ°ãããã§äœ¿çšãããŸãããŸãããŸãã¯Android Studioãä»ããŠJavaããå€æãããŸãïŒã
- å¥ã®ã¯ã©ã¹ããç¹å®ã®é¢æ°ïŒãªããžããªãã¢ã¯ãã£ããã£ãªã©ïŒãåŒã³åºããŸãã
- ã¹ã±ãžã¥ãŒã©ãå®è¡ããã¹ã¬ããã決å®ããçµæãè¿ããŸãïŒã¡ãœãã.subscribeOnïŒïŒããã³.observeOnïŒïŒ ïŒã
- ç»é²è§£é€ã®ããã«ãªããžã§ã¯ããžã®ãªã³ã¯ãä¿åããŸãïŒããšãã°ãCompositeObservableã«ïŒã
- ã€ãã³ãã®ã¹ããªãŒã ã賌èªããŸãã
- ã¢ã¯ãã£ããã£ã©ã€ããµã€ã¯ã«ã®ã€ãã³ãã«å¿ããŠãã¹ããªãŒã ã®è³Œèªã解é€ããŸãã
ããã¯ãRxã䜿çšããããã®åºæ¬çãªã¢ã«ãŽãªãºã ã§ãïŒãããã³ã°é¢æ°ãä»ã®ããŒã¿æäœã®è©³çŽ°ã¯èæ ®ããŠããŸããïŒã ã³ã«ãã³ã«é¢ããŠã¯ãååã¯ããŸãå€ãããŸããã åãæŠå¿µãçšèªã®ã¿ãå€æŽãããŠããŸãã
- corutinã®ã¢ããã¿ãŒã䜿çšããŠãRetrofitã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ããŸãã é¢æ°ã¯Corutin APIããDeferredãªããžã§ã¯ããè¿ããŸãã
- ãããã®é¢æ°ãå¥ã®ã¯ã©ã¹ïŒãªããžããªãã¢ã¯ãã£ããã£ãªã©ïŒããåŒã³åºããŸãã å¯äžã®éãïŒåæ©èœã¯suspendãšããŠããŒã¯ãããå¿ èŠããããŸãã
- ã³ã«ãŒãã³ã«äœ¿çšããããã£ã¹ãããã£ãŒãå®çŸ©ããŸãã
- 賌èªã解é€ããããã«Jobãªããžã§ã¯ããžã®ãªã³ã¯ãä¿åããŸãã
- å¯èœãªæ¹æ³ã§ã³ã«ãŒãã³ãå®è¡ããŸãã
- ã¢ã¯ãã£ããã£ã©ã€ããµã€ã¯ã«ã®ã€ãã³ãã«å¿ããŠã³ã«ãŒãã³ããã£ã³ã»ã«ããŸãã
äžèšã®ã·ãŒã±ã³ã¹ãããããããã«ãRxãšCorutinã®å®è¡ããã»ã¹ã¯éåžžã«äŒŒãŠããŸãã å®è£ ã®è©³çŽ°ãèæ ®ããªãå Žåãããã¯ãæ¢åã®ã¢ãããŒããç¶æã§ããããšãæå³ããŸã-å®è£ ãã³ã«ãŒãã³ã«åªãããã®ã«ããããã«ããã€ãã®ããšã眮ãæããã ãã§ãã
æåã«è¡ãå¿ èŠãããæé ã¯ãRetrofitãé 延ãªããžã§ã¯ããè¿ãããšãèš±å¯ããããšã§ãã é 延ãªããžã§ã¯ãã¯ãå¿ èŠã«å¿ããŠå ã«æ»ãããšãã§ããéããããã³ã°å ç©ã§ãã ãããã®ãªããžã§ã¯ãã¯ãæ¬è³ªçã«ã¯å¯Ÿå¿ãããžã§ãã®å€ãå«ãã³ã«ãŒãã³ãžã§ãã§ãã Deferredã¿ã€ãã䜿çšãããšãJobãšåãã¢ã€ãã¢ãçµã¿åãããŠãæåãŸãã¯å€±æãªã©ã®è¿œå ã®ç¶æ ãååŸããæ©èœãè¿œå ã§ããŸããããã«ããããããã¯ãŒã¯èŠæ±ã«æé©ã§ãã
RxJavaã§Retrofitã䜿çšããŠããå ŽåãRxJava Call Adapter Factoryã䜿çšããŠããå¯èœæ§ããããŸãã 幞ããªããšã«ãJake Wortonã¯åœŒå¥³ã®åçã®ã³ã«ãŒãã³ãæžããã
Retrofitãã«ããŒã§ãã®åŒã³åºãã¢ããã¿ãŒã䜿çšããŠãRxJavaãšåãæ¹æ³ã§Retrofitã€ã³ã¿ãŒãã§ãŒã¹ãå®è£ ã§ããŸãã
private fun makeService(okHttpClient: OkHttpClient): MyService { val retrofit = Retrofit.Builder() .baseUrl("some_api") .client(okHttpClient) .addCallAdapterFactory(CoroutineCallAdapterFactory()) .build() return retrofit.create(MyService::class.java) }
次ã«ãäžèšã§äœ¿çšãããŠããMyServiceã€ã³ã¿ãŒãã§ã€ã¹ãèŠãŠã¿ãŸãããã Retrofitã€ã³ã¿ãŒãã§ã€ã¹ã§è¿ãããObservableåãDeferredã«çœ®ãæããå¿ èŠããããŸãã 以åã¯æ¬¡ã®ããã§ããïŒ
@GET("some_endpoint") fun getData(): Observable<List<MyData>>
次ã®ããã«çœ®ãæããŸãïŒ
@GET("some_endpoint") fun getData(): Deferred<List<MyData>>
getDataïŒïŒãåŒã³åºããã³ã«ãDeferredãªããžã§ã¯ããè¿ãããŸããããã¯ããããã¯ãŒã¯èŠæ±ã®Jobã«çžåœããŸãã 以åã¯ãRxJavaã§ãã®é¢æ°ãäœããã®æ¹æ³ã§åŒã³åºããŠããŸããã
override fun getData(): Observable<List<MyData>> { return myService.getData() .map { result -> result.map { myDataMapper.mapFromRemote(it) } } }
ãã®RxJavaã¹ããªãŒã ã§ã¯ããŠãŒãã£ãªãã£é¢æ°ãåŒã³åºããRxJava APIãããããæäœãé©çšããŠããªã¯ãšã¹ãããè¿ãããããŒã¿ãUIã¬ã€ã€ãŒã§äœ¿çšããããã®ã«ãããã³ã°ããŸãã ã³ã«ãŒãã³ã䜿çšããå®è£ ã䜿çšãããšãããã¯å°ãå€ãããŸãã ãŸããé¢æ°ã®æ¬äœå ã§é 延æäœãå®è¡ããã«ã¯ãé¢æ°ãäžæ ïŒé å»¶ïŒ ããå¿ èŠããããŸãã ãŸãããã®ããã«ãåŒã³åºãé¢æ°ã延æããå¿ èŠããããŸãã é 延é¢æ°ã¯éããããã³ã°ã§ãããæåã«åŒã³åºãããåŸã«å¶åŸ¡ã§ããŸãã éå§ãäžæåæ¢ãåéããã£ã³ã»ã«ã§ããŸãã
override suspend fun getData(): List<MyData> { ... }
次ã«ããŠãŒãã£ãªãã£é¢æ°ãåŒã³åºãå¿ èŠããããŸãã äžèŠãåãããšãããŠããŸããã Observableã§ã¯ãªãDeferredã«ãªã£ãããšãèŠããŠããå¿ èŠããããŸãã
override suspend fun getData(): List<MyData> { val result = myService.getData() ... }
ãã®å€æŽã«ãããRxJava APIã®ãããæäœãã§ãŒã³ã䜿çšã§ããªããªããŸããã ãããŠãã®æç¹ã§ããããŒã¿ã¯å©çšã§ããŸãã-Deferredã€ã³ã¹ã¿ã³ã¹ãããããŸããã ããã§ãã¯ãšãªã®çµæãåŸ ã€ããã«awaitïŒïŒé¢æ°ã䜿çšããé¢æ°å ã®ã³ãŒãã®å®è¡ãç¶ç¶ããå¿ èŠããããŸãã
override suspend fun getData(): List<MyData> { val result = myService.getData().await() ... }
ãã®æç¹ã§ãå®äºãããªã¯ãšã¹ããšãã®ããŒã¿ã䜿çšã§ããããã«ãªããŸãã ãããã£ãŠããããã³ã°æäœãå®è¡ã§ããããã«ãªããŸããã
override suspend fun getData(): List<MyData> { val result = myService.getData().await() return result.map { myDataMapper.mapFromRemote(it) } }
Retrofitã€ã³ã¿ãŒãã§ãŒã¹ãåŒã³åºãã¯ã©ã¹ãšäžç·ã«äœ¿çšããã³ã«ãŒãã³ã䜿çšããŸããã ããã§ãActivityãŸãã¯ãã©ã°ã¡ã³ããããã®ã³ãŒããåŒã³åºãããããã¯ãŒã¯ããååŸããããŒã¿ã䜿çšããŸãã
ã¢ã¯ãã£ããã£ã§ã¯ãJobãžã®ãªã³ã¯ãäœæããããšããå§ããŸãããã®ãªã³ã¯ã«ã³ã«ãŒãã³æäœãå²ãåœãŠãããã䜿çšããŠã onDestroyïŒïŒåŒã³åºãäžã«èŠæ±ã®ãã£ã³ã»ã«ãªã©ãå¶åŸ¡ããŸãã
private var myJob: Job? = null override fun onDestroy() { myJob?.cancel() super.onDestroy() }
ããã§ãmyJobå€æ°ã«äœããå²ãåœãŠãããšãã§ããŸãã ã³ã«ãŒãã³ã䜿çšããŠãªã¯ãšã¹ããèŠãŠã¿ãŸãããã
myJob = CoroutineScope(Dispatchers.IO).launch { val result = repo.getLeagues() withContext(Dispatchers.Main) { //do something with result } }
ãã®æçš¿ã§ã¯ãããã¯ä»ã®æçš¿ã®ãããã¯ã§ãããããDispatcherãæãäžããããã³ã«ãŒãã³å ã§æäœãå®è¡ãããããããšã¯ããããããŸããã èŠããã«ãããã§äœãèµ·ãããïŒ
- IO Dispatcherããã©ã¡ãŒã¿ãŒãšããŠäœ¿çšããŠCoroutineScopeã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã ãã®ãã£ã¹ãããã£ã¯ããããã¯ãŒã¯èŠæ±ãªã©ã®ããããã³ã°I / Oæäœãå®è¡ããããã«äœ¿çšãããŸãã
- launché¢æ°ã§ã³ã«ãŒãã³ãèµ·åããŸã-ãã®é¢æ°ã¯æ°ããã³ã«ãŒãã³ãèµ·åããJobåã®å€æ°ãžã®ãªã³ã¯ãè¿ããŸãã
- 次ã«ããªããžããªãžã®ãªã³ã¯ã䜿çšããŠããããã¯ãŒã¯èŠæ±ãå®è¡ããŠããŒã¿ãåä¿¡ããŸãã
- æåŸã«ãã¡ã€ã³ãã£ã¹ãããã£ãŒã䜿çšããŠUIã¹ã¬ããã§äœæ¥ãè¡ããŸãã ããã§ãåä¿¡ããããŒã¿ããŠãŒã¶ãŒã«è¡šç€ºã§ããŸãã
次ã®æçš¿ã§ã¯ãèè ã¯è©³çŽ°ãããå°ãæãäžããããšãçŽæããŸãããã³ã«ãŒãã³ã®ç 究ãå§ããã«ã¯çŸåšã®è³æã§ååãªã¯ãã§ãã
ãã®æçš¿ã§ã¯ãRetrofitå¿çã®RxJavaå®è£ ãCorutin APIã®Deferredãªããžã§ã¯ãã«çœ®ãæããŸããã ãããã®é¢æ°ãåŒã³åºããŠãããã¯ãŒã¯ããããŒã¿ãååŸããã¢ã¯ãã£ããã£ã«è¡šç€ºããŸãã ã³ã«ãŒãã³ã®äœ¿çšãéå§ããããã«å¿ èŠãªå€æŽãã©ãã ãå°ãªãããç解ããç¹ã«ã³ãŒãã®èªã¿åããšæžã蟌ã¿ãè¡ãéã«APIã®ã·ã³ãã«ããé«ãè©äŸ¡ããŠãã ããã
å ã®æçš¿ã®ã³ã¡ã³ãã§ãç§ã¯äŒçµ±çãªãªã¯ãšã¹ããèŠã€ããŸããïŒã³ãŒãå šäœã衚瀺ããŸãã ãããã£ãŠãèµ·åæã«YandexãSchedules APIã䜿çšããŠåè»ã®ã¹ã±ãžã¥ãŒã«ãåãåããRecyclerViewã«è¡šç€ºããåçŽãªã¢ããªã±ãŒã·ã§ã³ãäœæããŸããã ãªã³ã¯ïŒ https : //github.com/AndreySBer/RetrofitCoroutinesExample
ãŸããã³ã«ãŒãã³ã¯ãã¹ã¬ãããåæããããã®åçã®æäœã»ãããæäŸããªããããRxJavaã®å£ã£ã代æ¿ãšæãããããšãä»ãå ããŸãã ãã®ç¹ã§ãKotlinã®ReactiveXå®è£ RxKotlinãèŠã䟡å€ããããŸãã
Android Jetpackã䜿çšããŠããå ŽåãRetrofitãã³ã«ãŒãã³ãLiveDataãMVVMã®äŸãèŠã€ããŸããïŒ https ://codinginfinite.com/kotlin-coroutine-call-adapter-retrofit/