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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
340
Android accessibility and automated check tools
itome
1
5.1k
Accessibility in CATS
itome
4
2.5k
Introduce_Owl.pdf
itome
0
120
Introducing Android Accessibility Test with Accessibility Testing Framework
itome
1
800
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
AIエージェントが名古屋の猛暑からあなたを守る
happysamurai294
0
120
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
0
2.3k
機械学習を「社会実装」するということ 2026年夏版 / Social Implementation of Machine Learning June 2026 Version
moepy_stats
5
2.4k
小さく始める AI 活用推進 ― 日経電子版 Web チームの事例/nikkei-tech-talk47
nikkei_engineer_recruiting
0
270
LayerX コーポレートエンジニアリング室におけるサプライチェーンセキュリティへの取り組み / Supply Chain Security at LayerX Corporate Engineering
yuyatakeyama
2
380
On-behalf-of Token exchange with AgentCore Identity
hironobuiga
2
220
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
1k
自宅LLMの話
jacopen
1
580
いまさら聞けない「仕様駆動開発入門」 〜AI活用時代の開発プロセスを考える〜
findy_eventslides
1
100
FinOps × AIエージェントで実現する コストインシデントの自動調査
oasis1994liveforever
0
140
SONiCで構築・運用する生成AI向けパブリッククラウドネットワーク ~実装編~
sonic
0
210
やさしいA2A入門
minorun365
PRO
12
1.9k
Featured
See All Featured
Mind Mapping
helmedeiros
PRO
1
250
Practical Orchestrator
shlominoach
191
11k
Faster Mobile Websites
deanohume
310
31k
Unsuck your backbone
ammeep
672
58k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
460
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
300
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
730
For a Future-Friendly Web
brad_frost
183
10k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
330
The Limits of Empathy - UXLibs8
cassininazir
1
360
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