Trago à sua atenção uma tradução do artigo original de Mike Nakhimovich

Era uma vez, trabalhei no New York Times e criei uma biblioteca chamada Store
"a biblioteca Java para carregamento fácil e responsivo de dados". Criamos a loja usando RxJava
modelos retirados da implementação do cache do Guava . Os usuários de aplicativos de hoje esperam que as atualizações de dados ocorram na interface do usuário sem ter que fazer coisas como puxar para atualizarpara atualizar dados ou alternar entre telas. O front-end reativo me fez pensar em como podemos ter data warehouses declarativos com APIs simples que abstraem funções complexas como otimização multitarefa e cache de disco, necessárias em aplicativos móveis modernos. Em seus três anos de operação, a Store possui 45 colaboradores e mais de 3.500 estrelas do GitHub. A partir de agora, tenho o prazer de anunciar que o Dropbox assumirá o desenvolvimento ativo da loja e o lançará totalmente no Kotlin, com suporte para Coroutines
e Flow
. E agora Store 4
, esta é uma oportunidade de aproveitar o que aprendemos repensando a API e as necessidades atuais do ecossistema Android.
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