Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Use MVI Architecture in Kotlin × Android
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
itome
November 15, 2018
Technology
1.6k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Use MVI Architecture in Kotlin × Android
itome
November 15, 2018
More Decks by itome
See All by itome
今日始め るCloudflare Browser Rendering
itome
2
350
Android accessibility and automated check tools
itome
1
5.1k
Accessibility in CATS
itome
4
2.6k
Introduce_Owl.pdf
itome
0
120
Introducing Android Accessibility Test with Accessibility Testing Framework
itome
1
820
Introduction of accessibility for mobile development
itome
0
260
Architecture_for_mobile_development.pdf
itome
0
280
Android_Accessibility_Suite.pdf
itome
0
170
Introducing Owl
itome
0
1.2k
Other Decks in Technology
See All in Technology
20260817_生成AIの動向と中学校・高等学校での活用を考える_v1.00_公開用
doradora09
PRO
0
200
AIのためのEthernet技術動向 (SerDes)
markunet
1
300
内製AIチャットボット開発で学んだ Datadog Agent Observability活用術
mkdev10
0
120
長期運営で肥大化したExcelマスターデータの解消に向けた移行事例
gree_tech
PRO
0
340
AI時代に、人は何を、どう学ぶのか #pbl_pub / What and How Do We Learn in the AI Era?
takaking22
1
240
コーチングの奥義 何もしないテクニック
jinwatanabe
0
150
同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す
kuroneko13
0
270
なぜ Temporal の大小比較には compare しかないのか / Why Does Temporal Only Have compare() for Comparisons
kazukihayase
1
200
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.6k
ハッカソンで入賞した話 @ Findy LT
asari194617
0
1.5k
強化学習「理論」入門
enakai00
3
3.6k
LanceDB入門
mocobeta
9
670
Featured
See All Featured
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
710
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Curse of the Amulet
leimatthew05
2
14k
We Have a Design System, Now What?
morganepeng
55
8.3k
Design in an AI World
tapps
1
290
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
A designer walks into a library…
pauljervisheath
211
24k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Designing for Timeless Needs
cassininazir
1
450
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
How to Ace a Technical Interview
jacobian
281
24k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Transcript
Koin×AndroidͰMVI ΞʔΩςΫνϟΛ࠾༻͢Δ #potatetips #56
ࣗݾհ 0min
ࣗݾհ 0min ௩ຊࢤ ! https://twitter.com/itometeam " https://github.com/itome # https://medium.com/@itometeam cyberagent/cats
MVI Architectureͱʁ 1min
MVI Architectureͱʁ 1min ୯ํσʔλϑϩʔ • Model • View • Intent(≠android.content.Intent)
ViewModelͰ Intent → Action → Result → Result ͱσʔλΛม͍ͯ͘͜͠ͱͰ ঢ়ଶΛมߋ͢Δ
RxʹΑΔ࣮ྫ 2min
RxʹΑΔ࣮ྫ 2min sealed class EventsIntent : MviIntent { object FetchFirstPageIntent
: EventsIntent() data class FetchPageIntent(val pageNum: Int) : EventsIntent() object FetchLoginUserIntent : EventsIntent() } sealed class EventsAction : MviAction { object FetchFirstPageAction : EventsAction() data class FetchEventsPageAction( val pageNum: Int ) : EventsAction() object FetchLoginUserAction : EventsAction() }
RxʹΑΔ࣮ྫ 2min private fun actionFromIntent(intent: EventsIntent): EventsAction { return when
(intent) { FetchFirstPageIntent -> FetchFirstPageAction is FetchPageIntent -> FetchEventsPageAction(intent.pageNum) FetchLoginUserIntent -> FetchLoginUserAction } }
RxʹΑΔ࣮ྫ 2min sealed class EventsResult : MviResult { sealed class
FetchFirstPageResult : EventsResult() { data class Success(val events: List<Event>) : FetchFirstPageResult() data class Failure(val error: Throwable) : FetchFirstPageResult() object InFlight : FetchFirstPageResult() } sealed class FetchEventsPageResult : EventsResult() { data class Success(val events: List<Event>) : FetchEventsPageResult() data class Failure(val error: Throwable) : FetchEventsPageResult() object InFlight : FetchEventsPageResult() } sealed class FetchLoginUserResult : EventsResult() { data class Success(val user: User) : FetchLoginUserResult() data class Failure(val error: Throwable) : FetchLoginUserResult() object InFlight : FetchLoginUserResult() } }
RxʹΑΔ࣮ྫ 2min override val actionProcessor = mergeProcessor( fetchFirstPageProcessor to FetchFirstPageAction::class,
fetchEventsPageProcessor to FetchEventsPageAction::class, fetchLoginUserProcessor to FetchLoginUserAction::class ) private val fetchFirstPageProcessor = createProcessor<FetchFirstPageAction, FetchFirstPageResult> { repository.getEvents(1) .toObservable() .map { user -> FetchFirstPageResult.Success(user) } .cast(FetchFirstPageResult::class.java) .onErrorReturn(FetchFirstPageResult::Failure) .subscribeOn(schedulerProvider.io()) .observeOn(schedulerProvider.ui()) .startWith(FetchFirstPageResult.InFlight) }
RxʹΑΔ࣮ྫ 2min data class EventsViewState( val loginUser: User?, val events:
List<Event>, val error: Throwable?, val nextPage: Int, val isLoading: Boolean ) : MviViewState { companion object { fun idle(): EventsViewState { return EventsViewState( loginUser = null, events = emptyList(), error = null, nextPage = 1, isLoading = false ) } } }
RxʹΑΔ࣮ྫ 2min private val reducer = { previousState: EventsViewState, result:
EventsResult -> when (result) { is FetchFirstPageResult -> when (result) { is FetchFirstPageResult.Success -> previousState.copy( events = result.events, error = null, isLoading = false, nextPage = 2 ) is FetchFirstPageResult.Failure -> previousState.copy(error = result.error, isLoading = false) FetchFirstPageResult.InFlight -> previousState.copy(isLoading = true) }
RxʹΑΔ࣮ྫ 2min private fun compose(): Observable<EventsViewState> { return intentsSubject .map(this::actionFromIntent)
.compose(actionProcessorHolder.actionProcessor) .scan(EventsViewState.idle(), reducer) .replay(1) .autoConnect(0) }
RxʹΑΔ࣮ྫ 2min ιʔείʔυ https://github.com/itome/GithubMVI
ϝϦοτ / σϝϦοτ 2min
ϝϦοτ 2min ϓϩάϥϚʔʹର͢Δ੍͕ڧ͍ ςετ͕༰қ ɾਓʹΑ࣮͕ͬͯมΘΔ෦ΛͰ͖Δ͚ͩ͑ΒΕΔ ɾ֤ॲཧͰೖྗͱग़ྗ͕ඞͣ̍ΧॴʹͳΔͨΊɺ ɹςετ͖͢͜ͱ͕໌֬ ΤϥʔϋϯυϦϯά͕༰қ ɾViewͷΠϕϯτ͔ΒViewͷߋ৽·Ͱ͕ҰຊͷετϦʔϜʹ ɹͳ͍ͬͯΔͨΊɺྫ֎ॲཧ͕Θ͔Γ͍͢
σϝϦοτ 2min ̍ճ͖ΓͷΠϕϯτΛ͑Δͷ͕͍͠ ෳࡶͳϨΠΞτͰViewStateͷߋ৽ͷॲཧ͕ॏ͘ͳΔ ɾViewModelͷग़ྗ͕ViewStateͷΈͰ͋ΔͨΊɺҰճ͖ΓͷΠϕϯτΛ ɹViewModelଆ͔Βى͍ͨ࣌͜͠ɺflagΛ࣋ͨͤΔͳͲͷ͕ඞཁ ɾAndroidʹReactͷࠩߋ৽ͷΑ͏ͳΈ͕ଘࡏ͠ͳ͍ͨΊɺ ɹViewStateͷҰ෦Λߋ৽͚ͨͩ͠ͰɺViewStateʹؔ࿈͢Δ ɹશͯͷView͕ߋ৽͞Εͯ͠·͏ ʹͳΓ͍͢
ɾίʔυͷϘΠϥʔϓϨʔτ͕ଟ͍ͨΊɺখ͞ͳॲཧͰ͔ͳΓͷ ɹίʔυΛॻ͘ඞཁ͕͋Δɻ
·ͱΊ 0.5min
͋Γ͕ͱ͏͍͟͝·ͨ͠ ! https://twitter.com/itometeam " https://github.com/itome # https://medium.com/@itometeam Takeshi Tsukamoto cyberagent/cats