рд╕реНрдЯреЛрд░ рдХрд╛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рдирд╛: рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдирд╛

рдореИрдВ рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдорд╛рдЗрдХ рдирдЦрд┐рдореЛрд╡рд┐рдЪ рдХреЗ рдореВрд▓ рд▓реЗрдЦ рдХреЗ рдЕрдиреБрд╡рд╛рдж рдкрд░ рд▓рд╛рддрд╛ рд╣реВрдБ


рдПрдХ рдмрд╛рд░, рдореИрдВрдиреЗ рдиреНрдпреВрдпреЙрд░реНрдХ рдЯрд╛рдЗрдореНрд╕ рдореЗрдВ рдХрд╛рдо рдХрд┐рдпрд╛ рдФрд░ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмрдирд╛рдпрд╛ Store, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рдерд╛ "рдЖрд╕рд╛рди, рдЙрддреНрддрд░рджрд╛рдпреА рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпред" рд╣рдордиреЗ рдЕрдорд░реВрдж рдХреЗ рдХреИрд╢RxJava рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рд▓рд┐рдП рдЧрдП рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдЯреЛрд░ рдмрдирд╛рдпрд╛ ред рдЖрдЬ рдХреЗ рдРрдк рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдпреВрдЖрдИ рдореЗрдВ рдкреБрд▓-рдЯреВ-рд░рд┐рдлреНрд░реЗрд╢ рдЬреИрд╕реЗ рдХрд╛рдо рдХрд┐рдП рдмрд┐рдирд╛ рдбреЗрдЯрд╛ рдЕрдкрдбреЗрдЯ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВрдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рд╕реНрдХреНрд░реАрди рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рддрд╛рдЬрд╝рд╛ рдХрд░рдиреЗ рдпрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рджреГрд╢реНрдпрдкрдЯрд▓ рдиреЗ рдореБрдЭреЗ рдпрд╣ рд╕реЛрдЪрдиреЗ рдкрд░ рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдХрд┐ рдХреИрд╕реЗ рд╣рдо рд╕рд╛рдзрд╛рд░рдг рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рдШреЛрд╖рдгрд╛рддреНрдордХ рдбреЗрдЯрд╛ рдЧреЛрджрд╛рдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рдорд▓реНрдЯреАрдЯрд╛рд╕реНрдХ рдереНрд░реЙрдЯрд▓рд┐рдВрдЧ рдФрд░ рдбрд┐рд╕реНрдХ рдХреИрд╢рд┐рдВрдЧ рдЬреИрд╕реЗ рдЬрдЯрд┐рд▓ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдп рд╣реИрдВ, рдЬреЛ рдЖрдзреБрдирд┐рдХ рдореЛрдмрд╛рдЗрд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВред рдЕрдкрдиреЗ рддреАрди рд╡рд░реНрд╖реЛрдВ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдореЗрдВ, рд╕реНрдЯреЛрд░ рдореЗрдВ 45 рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛ рд╣реИрдВ рдФрд░ 3,500 рд╕реЗ рдЕрдзрд┐рдХ рдЧреАрдерд╣рдм рд╕рд┐рддрд╛рд░реЗ рд╣реИрдВред рдЕрдм рд╕реЗ, рдореИрдВ рдШреЛрд╖рдгрд╛ рдХреА рдереА рдХрд┐ рдЦреБрд╢ рд╣реВрдБ рдбреНрд░реЙрдкрдмреЙрдХреНрд╕ рд╕реНрдЯреЛрд░ рдХреЗ рд╕рдХреНрд░рд┐рдп рд╡рд┐рдХрд╛рд╕ рдкрд░ рд▓реЗ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде Kotlin рдкрд░ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЬрд╛рд░реА рдХрд░реЗрдВрдЧреЗ CoroutinesрдФрд░ Flowред рдФрд░ рдЕрдм Store 4- рдпрд╣ рдПрдВрдбреНрд░реЙрдЗрдб рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдХреА рдПрдкреАрдЖрдИ рдФрд░ рд╡рд░реНрддрдорд╛рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреБрдирд░реНрд╡рд┐рдЪрд╛рд░ рдХрд░рдХреЗ рд╣рдордиреЗ рдЬреЛ рдХреБрдЫ рднреА рд╕реАрдЦрд╛ рд╣реИ, рдЙрд╕рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХрд╛ рдПрдХ рдЕрд╡рд╕рд░ рд╣реИред




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 :


// Observable.java
@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()

:


  • ,
  • API , , .

Store  . persister() Store. , Observable, Jetpack Room, SQLDelight Realm.


:


StoreтАи


 Store  . , Flow, , ReturnType.


val store = StoreBuilder.from {
                articleId -> api.getArticle(articleId) //Flow<Article>
            }
            .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:





Store : github.com/dropbox/Store




, , Android Open Source Project, , Creative Commons 2.5 Attribution License


All Articles