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
340
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
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
Amazon EVS で VCF 9.0 / 9.1 のサポート開始まとめ
mtoyoda
0
280
ゼロをイチにする仕事が終わったあと
smasato
0
310
初めてのDatabricks勉強会
taka_aki
2
240
AWS Blocks を触ってみた/first-tach-aws-blocks
fossamagna
2
150
生成AI活用によるODC欠陥分析の分類高速化の実践と導入効果 / 20260703 Suguru Ishii
shift_evolve
PRO
2
100
オブザーバビリティ、本当に活用できてる? 〜API連携×生成AIで成熟度を自動評価〜
dmmsre
1
2.1k
人を動かすのは時間ではなく、納得感 〜新任EMが入社3ヶ月、組織を2回変えた話〜
kakehashi
PRO
2
160
はじめてのWDM
miyukichi_ospf
1
120
AIで政治は変わるのか? — 中高生と考えたAI時代の民主主義(東海高校サタデープログラム)
eitarosuda
0
400
NDIAS CTF 2026 問題解説会資料
bata_24
0
180
脱金融のフューチャー・デザイン / Future Design Beyond Finance
ks91
PRO
0
140
Control Planeで育てるBtoB SaaSの認証基盤 - SRE NEXT 2026
pokohide
1
1.6k
Featured
See All Featured
Being A Developer After 40
akosma
91
590k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
260
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
240
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
410
Building an army of robots
kneath
306
46k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Context Engineering - Making Every Token Count
addyosmani
9
1k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
890
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
180
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
630
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