Ich mache Sie auf die Übersetzung des Originalartikels von Mike Nakhimovich aufmerksam

Es war einmal, als ich bei der New York Times arbeitete und eine Bibliothek namens Store
"Java-Bibliothek zum einfachen und reaktionsschnellen Laden von Daten" erstellte. Wir haben den Store mit RxJava
Vorlagen erstellt, die aus der Implementierung von Guavas Cache stammen . Heutige App-Benutzer erwarten, dass Datenaktualisierungen in der Benutzeroberfläche stattfinden, ohne dass sie beispielsweise zum Aktualisieren ziehen müssenum Daten zu aktualisieren oder zwischen Bildschirmen hin und her zu wechseln. Das reaktive Frontend ließ mich darüber nachdenken, wie wir deklarative Data Warehouses mit einfachen APIs haben können, die komplexe Funktionen wie Multitask-Drosselung und Festplatten-Caching abstrahieren, die in modernen mobilen Anwendungen erforderlich sind. In seinen drei Betriebsjahren hat Store 45 Mitwirkende und über 3.500 GitHub-Stars. Von nun an freue ich mich, Ihnen mitteilen zu können, dass Dropbox die aktive Entwicklung des Stores übernehmen und ihn mit Unterstützung für Coroutines
und vollständig auf Kotlin veröffentlichen wird Flow
. Und jetzt Store 4
- dies ist eine Gelegenheit, das Gelernte zu nutzen, indem wir die API und die aktuellen Anforderungen des Android-Ökosystems überdenken.
Android . . , , Google. , Android. Android Jetpack
:

, Android Jetpack :

https://developer.android.com/jetpack/docs/guide
- : , AndroidX , Lifecycle Scopes . , view- .
- View Model Live Data: , , ( , !).
- Room: SQLite, ORM RxJava .
- Remote Data Source: Jetpack, Retrofit Okhttp Square .
, , , ( , , Jetpack ;-) ). , . , Dropbox Store, , .
, Store, . ,
«… , , . , , , ».
. , , , . , .
Store?
, , Store, Android- . — , . , UX. , , . , . Store, .
, , . …

Store :

Store
, , Store, , , .
4 – Android . , . , Room SQLDelight, , . -, push-, Firebase, «» . Store , , , , , . , Store: http://github.com/dropbox/Store.
Store 4
. RxJava , Flow
.
, , , , RxJava? . , , . , . , , , , .
— . RxJava - . API RxJava :
@CheckReturnValue
public final Disposable subscribe(Consumer onNext) {}
, , RxJava Observable Disposable . dispose(), . . RxJava2 @CheckReturnValue
— , flowable.subscribe , . , , . , RxJava, .
RxJava , dispose(). . RxJava, , , Kotlin Flow , . , Flow . Flow , .
suspend fun Flow.collect(...)
Collect RxJava, , Flow. RxJava, collect()
"suspend"
. , ( async/await
), . Flow.collect
, , .
, Android ( ) , , . , Kotlin, , viewModelScope
Jetpack, , . , Android: , .
public fun CoroutineScope.launch(...)
viewModelScope.launch {
flow.collect{ handle(it) }
}
, Flow. Android. , AndroidX . , ViewModel, , Room Flow. , (Paging). Store , Android , .
, Store , Android, , , , Kotlin multi-platform, . RxJava Kotlin native/js 6000 .
Store?
Store . Store, Fetcher
, , , . , Store . Store Flow, — ! Store // , , .
Store
, Store. , :
StoreBuilder.fromNonFlow { api.fetchSubreddit(it, "10")}
.persister(
reader = db.postDao()::loadPosts,
writer = db.postDao()::insertPosts,
delete = db.postDao()::clearFeed)
.cachePolicy(MemoryPolicy)
.build()
:
Store . persister() Store. , Observable, Jetpack Room, SQLDelight Realm.
:
Store
Store . , Flow, , ReturnType.
val store = StoreBuilder.from {
articleId -> api.getArticle(articleId)
}
.build()
Store , , toString()
, equals()
hashCode()
. Fetcher . . , equals()
hashcode()
data- Kotlin.
: Stream
API, Store, :
fun stream(request: StoreRequest<Key>):Flow<StoreResponse>Output>>
StoreRequest
, , . StoreResponse
. StoreResponse — Kotlin, Loading
, Data
Error
. StoreResponse ResponseOrigin, , .

Loading
ResponseOrigin. .Data
, , Store.Error
, , ResponseOrigin.
Store , StoreResponse.Error
, Flow , , . - , render
/updateUI
. . :
lifecycleScope.launchWhenStarted {
store.stream(StoreRequest.cached(key = key, refresh=true)).collect { response ->
when(response) {
is StoreResponse.Loading -> showLoadingSpinner()
is StoreResponse.Data -> {
if (response.origin == ResponseOrigin.Fetcher) hideLoadingSpinner()
updateUI(response.value)
}
is StoreResponse.Error -> {
if (response.origin == ResponseOrigin.Fetcher) hideLoadingSpinner()
showError(response.error)
}
}
}
}
: Store.get(key)
, Store.stream(key)
Store.fresh(key)
.
suspend fun Store.get(key: Key): Value
— . , .suspend fun Store.fresh(key: Key): Value
— , .suspend fun Store.stream(key: Key): Flow
— (Flow
) .
get()
:
lifecycleScope.launchWhenStarted {
val article = store.get(key)
updateUI(article)
}
store.get(key), ( ), . store.get(key) , . ( ) , . , , , Store. Store . Store , , .
store.fresh(key)
( ). , fresh() , store.get()
/stream()
. fresh() pull-to-refresh
.
fresh()
get()
.
Stream
, store.stream(key)
, , , / . stream() , .
lifecycleScope.launchWhenStarted {
store.stream(StoreRequest.cached(3, refresh = false))
.collect{ }
store.stream(StoreRequest.get(3))
.collect{ }

, Store . , , , . , . Store.get() 12 . , . .
Store , persister()
. , , Store , , .
persister()
, Flow
Store . , , Store, Store.
, Observable (Jetpack Room, SQLDelight Realm), , , UX.
StoreBuilder.fromNonFlow {api.fetchSubreddit(it, "10")}
.persister(
reader = db.postDao()::loadPosts,
writer = db.postDao()::insertPosts,
delete = db.postDao()::clearFeed)
.cachePolicy(MemoryPolicy)
.build()
Store , . , Store (Realm, SQLite, Firebase ..). SQLite Room, Jetpack.
API Store — , . :
- , Room
- (
StoreRequest
) - (
stream
) - API, Kotlin.
, Store. , , Android, . , -, - . , , .
KotlinConf:
, , Android Open Source Project, , Creative Commons 2.5 Attribution License