Общий жизненный цикл ViewModel для Android JetPack - PullRequest
0 голосов
/ 10 ноября 2018

Документация https://developer.android.com/topic/libraries/architecture/viewmodel#sharing описывает, как мы можем совместно использовать одну и ту же модель представления для разных фрагментов.

У меня есть несколько сложных страниц в моем одном приложении Activity с контейнером и фрагментами вкладок. Каждая такая страница имеет собственную ViewModel, которая должна быть доступна всем содержащимся фрагментам.

Ключевым трюком здесь является использование Activity вместо Fragment для хранения моей ViewModel.

Проблема в том, что моя активность может иметь несколько страниц с собственными моделями, и хранение модели представления для конкретной страницы все время является пустой тратой ресурсов устройства.

Есть ли способ контролировать жизненный цикл ViewModel, чтобы уничтожить его, когда пользователь покидает страницу?

Я думал использовать фрагмент контейнера вместо Activity:

model = ViewModelProviders.of(getPageContainerFragment()).get(SharedViewModel.class);

Но нашел эту идею не очень хорошей, потому что все дочерние фрагменты должны знать о родителе, что может быть не так хорошо.

Есть ли альтернативы, чтобы правильно заняться таким делом?

1 Ответ

0 голосов
/ 13 апреля 2019

Если я правильно понял, ваш вопрос «как освободить ресурсы», а не «как очистить viewmodel».
Таким образом, вы можете сделать ваши модели просмотра как можно более светлыми, например:

abstract class MyViewModel: ViewModel() {
    abstract fun freeResources()
}

и вызовите vm.freeResources() в вашем OnPageChangeListener или OnTabSelectedListener или любом другом прослушивателе, который вы используете, при изменении страницы.
В этом случае вы должны получить viewModel, используя область действия.

В качестве альтернативы, если вы действительно хотите, чтобы ваша модель представления была onCleared(), а затем была создана новая, я могу предложить использовать библиотеку scoped-vm . Это позволяет вам запрашивать модели представления для области, идентифицируемой строковым именем.

ScopedViewModelProviders
     .forScope(fragment, "scope")
     .of(activity)
     .get(MyViewModel::class.java)

Область действия очищается (как и модели представления в ней), как только последний фрагмент, который запросил что-то из этой области, будет уничтожен. Так что используйте разные рамки для своих страниц.
Но в этом случае вам следует дважды проверить жизненный цикл ваших фрагментов: если ваш PagerAdapter хранит их для повторного использования, область действия никогда не будет очищена, и вам поможет только ручной подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...