android / architecture-samples

A collection of samples to discuss and showcase different architectural tools and patterns for Android apps.
Apache License 2.0
44.5k stars 11.65k forks source link

[master] Filtering state is lost across process death #663

Closed Zhuinden closed 4 years ago

Zhuinden commented 5 years ago

Value of _currentFiltering is never persisted to Bundle. If one were to use SavedStateHandle to solve, this, the solution would look like this:

    class TasksViewModel(
        private val tasksRepository: TasksRepository,
        private val savedStateHandle: SavedStateHandle
    ): ViewModel() {
        private val selectedFilter: MutableLiveData<TasksFilterType> = savedStateHandle.getLiveData("filterType")

        val items: LiveData<List<Task>> = selectedFilter.switchMap { filterType ->
            tasksRepository.getTasks(filterType)
        }        
    }

The Repository (or getTaskUseCase, whichever is used) should select the right DAO method to call for getting filtered results from Room DAO

    class TaskRepository(
        private val taskDao: TaskDao
    ) {
        fun getTasks(filterType: TasksFilterType): LiveData<List<Task>> = when(filterType) {
            ALL -> taskDao.getAllTasks()
            ACTIVE_ONLY -> taskDao.getActiveTasks()
            COMPLETED_ONLY -> tasks.getCompletedTasks()
        }
    }

And the DAO should expose LiveData with the correct filters

    @Query("SELECT * FROM Tasks")
    fun getAllTasks(): LiveData<List<Task>>

    @Query("SELECT * FROM Tasks WHERE completed = 1")
    fun getCompletedTasks(): LiveData<List<Task>>

    @Query("SELECT * FROM Tasks WHERE completed = 0")
    fun getActiveTasks(): LiveData<List<Task>>
JoseAlcerreca commented 5 years ago

On SavedStateHandle: good point, will update that.

On filtering in the data layer: obvious thing to do in a real app, but in blueprints we use filtering as business logic to showcase how to do operations off the main thread. Same in the usecases branch. Not ideal, but adding more complexity would make the sample harder to follow.

Many thanks!

Zhuinden commented 4 years ago

Now with the ViewModel-SavedState module reaching 1.0.0, the filtering can be persisted using SavedStateHandle.

https://github.com/android/architecture-samples/blob/6f21231be28080fda229b8bbd738e962ea4bf95d/app/src/main/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksViewModel.kt#L63

JoseAlcerreca commented 4 years ago

Added in #700 without LiveData and converting enum to ints since apparently there's no support for enums.

Zhuinden commented 4 years ago

No support for enums? that's odd, enums should (or I would expect them to) fall back to putSerializable. 🤔

If this is intended, then that is quite an unfortunate limitation. One could use the enum name or ordinals I guess but that is still inconvenient.

JoseAlcerreca commented 4 years ago

They are, my bad. I was simulating process death incorrectly.