我提请您注意Mike Nakhimovich 的原始文章翻译
![](https://habrastorage.org/webt/6t/au/jn/6taujnsajuag-id6inmec79hzyk.jpeg)
曾几何时,我在《纽约时报》工作,并创建了一个名为的库Store
,该库是“用于轻松,响应式地加载数据的Java库”。我们使用RxJava
从Guava的Cache实现中获取的模板创建了Store 。当今的应用程序用户期望在用户界面中进行数据更新,而无需执行如需刷新的操作刷新数据或在屏幕之间来回移动。响应式前端使我想到了如何使用简单的API来创建声明性数据仓库,该API可以抽象化复杂的功能,如多任务调节和磁盘缓存,这是现代移动应用程序所必需的。在运营的三年中,Store拥有45位贡献者和超过3500个GitHub star。从现在开始,我很高兴地宣布,Dropbox将积极参与Store的开发,并将在Kotlin上全面发布并支持Coroutines
and Flow
。现在Store 4
,这是一个通过重新思考API和Android生态系统当前需求来利用我们所学知识的机会。
Android . . , , Google. , Android. Android Jetpack
:
![](https://habrastorage.org/getpro/habr/post_images/546/2b9/b31/5462b9b31588ef7fce4b15eea947397e.jpg)
, Android Jetpack :
![](https://habrastorage.org/getpro/habr/post_images/1ec/d4f/dba/1ecd4fdba4c9605dd497c2f474d1e108.gif)
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, .
, , . …
![](https://habrastorage.org/getpro/habr/post_images/410/e26/23e/410e2623efbcd878a166018cc45a90fd.gif)
Store :
![](https://habrastorage.org/getpro/habr/post_images/4f7/d34/74f/4f7d3474f03894b341b50b678f300fa5.gif)
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, , .
![](https://habrastorage.org/getpro/habr/post_images/de3/a83/850/de3a838508a04e1a6b5fb4f3cfd8cf5b.jpg)
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{ }
![](https://habrastorage.org/getpro/habr/post_images/476/8e2/829/4768e2829ff60e04bcd7b7d20590e420.gif)
, 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