tgoop.com/dev_easy_notes/160
Last Update:
{2/2} По началу все с презрением относились к этой технологии, потому как тогда было модно хейтить Гугл за их неудобные и багующие либы. В целом за эти 5 лет ничего не поменялось. Однако за это время все признали ViewModel и по сути сейчас это основной способ хранить данные м/у убийствами View и весьма удобный.
ViewModel удобен тем, что можно делать хоть по 100 мелких на Activity или фрагмент. Плюс к этому есть метод для очистки, который точно дернется системой когда ViewModel умрет. Однако есть пара минус в том, что для проверки работы ViewModel нужно прям крутить экран, потому как Moxy можно было проверять при помощи настройки “Don’t keep Activities”. А ViewModel ломаются с этой настройкой, потому как считают что в этом случае ты сам ушел с экрана.
У ViewModel явное преимущество над другими решениями в том, что код по работе с ViewModel встроен в Activity. Встроен не в обычную Activity, а в ту которая идет с Jetpack. На самом деле встроен не сильно, там лишь добавили пару методов для удобства, при желании можно сделать свою реализацию ViewModel.
ViewModel работает несколько хитрее нежели Moxy. Они сохраняются не в статике, а в ActivityRecord. В предыдущих постах я писал про ActivityThread, которая умеет кучу всего. Так вот, в этом самом ActivityThread хранится список ActivityRecord, это некоторые данные по Activity, которые будут жить пока мы с Activity не уйдем, т.е даже между поворотами.
Как я уже сказал выше, мы можем сделать нашу собственную реализацию ViewModel. Для этого нужно использовать метод переопределить метод onRetainNonConfigurationInstance
. Если вы унаследовали свою Activity от любой Activity которая идет в Jetpack, у вас не получить переопределить этот метод, потому как в Activity Jetpack этот метод помечен как final.
Однако поиграться все равно можно, через метод onRetainCustomNonConfigurationInstance
(не путайте с предыдущим). В этом методе нужно вернуть объект, какой вашей душе угодно. Допустим будем возвращать HashMap<String, CustomViewModel>
. После всех переворотов, мы можем получить наши данные через метод getLastCustomNonConfigurationInstance
. Вот так, можно легко и просто сохранить данные без Bundle.
Ровно такой механизм и используют ViewModel. ViewModelStore
(который используется в ViewModelProvider) это буквально и есть HashMap<String, ViewModel>
. Разумеется если ваш процесс умрет, умрут и данные сохраненные через onRetainNonConfigurationInstance, и соответственно все ViewModel, но вы это и так знали.
Метод onRetainCustomNonConfigurationInstance
помечен как deprecated, и вместо него гугл рекомендует использовать ViewModel. По мне так это правильно, не хотелось бы приходя на проект видеть велосипед с этим методом.
Значит теперь пара советов по использованию ViewModel. Не страдайте фигней и сразу подключайте ktx и используйте делегаты. Дальше за вас все сделает система, главное правильно интегрируйтесь с DI. Большинство DI сами умеют работать с ViewModel. Что почитать:
👉 Официальная дока по ViewModel это must have и в целом там очень доступно все написано
👉 Тоже с официальной доки, туториал который должен помочь
Ну и совет, не тащите LiveData, предпочитайте Kotlin Flow или Rx.
Вот теперь вопрос к публике: вспомните дурацкое поведение фрагментов, и задумайтесь, а очистится ли ViewModel в таком фрагменте?
BY Dev Easy Notes
Share with your friend now:
tgoop.com/dev_easy_notes/160