Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Redux for Android

Redux for Android

It may be an unpopular opinion, but I recently found an amazing architectural pattern from the Javascript world. Ok, ok, before you go let me ask you this… do you like code that is easier to debug? How about a single source of truth and more deterministic code paths? Still with me? Let’s talk about Redux and how Redux can help simplify your architecture and your life. Worried that you won’t be able to use any of the nice lifecycle aware libraries Google created for us? Redux still works with Android Architecture components so we will also look at how we can utilize Live Data and View Models as well as other popular libraries and technologies.

Elliott Chenger

August 26, 2019
Tweet

More Decks by Elliott Chenger

Other Decks in Technology

Transcript

  1. “It Depends” Is The Answer To Your Android Question -

    Sam Edwards MVWTF: Demystifying Architecture Patterns - Adam McNeilly @echenger sli.do#3073
  2. Modern Architectures M V C M V P M V

    I M V V M @echenger sli.do#3073
  3. Presentation Layer Store State Login Feed Inbox Profile List Detail

    dispatch() onStateChanged() @echenger sli.do#3073
  4. override fun reduce(state: AppState, action: Action?): AppState { return when

    (action) { is SetSearchText -> { return state.copy(searchTerm = searchTerm) } else -> state } } @echenger sli.do#3073
  5. override fun reduce(state: AppState, action: Action?): AppState { return when

    (action) { is SetSearchText -> { return state.copy(searchTerm = searchTerm) } is ExecuteSearch -> { return state.copy(isLoading = true) } is ImageSearchResponseAction -> { return state.copy( isLoading = false, imageCollection = imageCollection ) } else -> state } } @echenger sli.do#3073
  6. override fun reduce(state: AppState, action: Action?): AppState { return when

    (action) { is Reducible -> { action.reduce(state) } else -> state } } @echenger sli.do#3073
  7. data class SetSearchText(val searchTerm: String) : ListAction(), Reducible { override

    fun reduce(state: AppState): AppState { return state.copy(searchTerm = searchTerm) } } class ExecuteSearch : ListAction(), Reducible { override fun reduce(state: AppState): AppState { return state.copy(isLoading = true) } } data class ImageSearchResponseAction(val imageCollection: ImageCollection) : ListAction(), Reducible { override fun reduce(state: AppState): AppState { return state.copy( isLoading = false, imageCollection = imageCollection ) } } @echenger sli.do#3073
  8. class ListViewModel(application: Application) : AndroidViewModel(application), StoreSubscriber<AppState> { val uiModelLiveData =

    MutableLiveData<MainUiModel>() private val store: StoreType<AppState> = (application as App).store init { store.subscribe(this) } fun onSearch(searchTerm: String) { val searchAction = SetSearchText(searchTerm) store.dispatch(searchAction) } override fun newState(state: AppState) { val state = store.state uiModelLiveData.value = MainUiModel.fromListState(state.listState) } override fun onCleared() { store.unsubscribe(this) } } @echenger sli.do#3073
  9. override fun newState(state: AppState) { val state = store.state uiModelLiveData.value

    = MainUiModel.fromListState(state.listState) } @echenger sli.do#3073
  10. class LoggingMiddleware : Middleware<AppState> { override fun dispatch(store: Store<AppState>, next:

    Dispatcher, action: Action): Action { Log.d("APP", "Dispatching $action") Log.d("APP", "SearchTeam before reducer ${store.state.listState.searchTerm}") val nextAction = next.dispatch(action) Log.d("APP", "SearchTeam after reducer ${store.state.listState.searchTerm}") return nextAction } } @echenger sli.do#3073
  11. Store State Middleware Reducer isLoading = true @echenger sli.do#3073 This

    slide won’t make sense until the talk video is up because it has lots of animations!