Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Use MVI Architecture in Kotlin × Android
Search
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
360
Android accessibility and automated check tools
itome
1
5.1k
Accessibility in CATS
itome
4
2.6k
Introduce_Owl.pdf
itome
0
130
Introducing Android Accessibility Test with Accessibility Testing Framework
itome
1
830
Introduction of accessibility for mobile development
itome
0
260
Architecture_for_mobile_development.pdf
itome
0
290
Android_Accessibility_Suite.pdf
itome
0
170
Introducing Owl
itome
0
1.2k
Other Decks in Technology
See All in Technology
AI-DLCって実際どう? 〜聞きたいこと全部聞いてみる〜
news_it_enj
0
250
目の前の楽しいが人生を変える - コミュニティの螺旋の歩き方と楽しむコツ / change your life
soudai
PRO
4
370
日経電子版を支えていく Kasane Design System/fec_fukuoka
nikkei_engineer_recruiting
0
630
AIネイティブプロダクトで顧客価値を最大化するプロダクトエンジニアとFDEの協働
righttouch
PRO
0
220
Webとヘルスデータ
yukukotani
1
360
幾何アルゴリズムで なめらかなピン操作を / iOSDC Japan 2026 / smoothpin
kazumanagano
0
250
プロダクト思考 × 基盤思考を AIで実現する Compound Engineering
tkc66buzz
1
310
ASTを使って影響範囲を特定する
nealle
0
140
【視聴者参加型!】AWSセキュリティアンチパターンクイズ
syoshie
1
490
20260912_スクラムにジェネラリストは必要か
ryugen04
0
310
Sigmaユーザーのための有用リソース一挙公開 & Sigmaで使えるMCP #sigma_ucj /useful-resources-for-sigma-computing-users-and-mcps-with-sigma
shinyaa31
0
180
多層防御と最⼩権限で実現する、安全なAIエージェント設計パターン
lycorptech_jp
PRO
1
250
Featured
See All Featured
Evolving SEO for Evolving Search Engines
ryanjones
0
280
Game over? The fight for quality and originality in the time of robots
wayneb77
1
270
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
510
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.6k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.2k
So, you think you're a good person
axbom
PRO
2
2.1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
400
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