Перейти к содержанию

Legacy DI

В старых Android-проектах Dagger или Toothpick часто соседствуют с MVP, Moxy и RxJava. Dependency injection (DI, внедрение зависимостей) отвечает за создание и связывание объектов; Moxy - фреймворк для слоя представления, а не DI-контейнер. Перед изменениями нужно проследить и граф зависимостей, и жизненный цикл экрана.

Dagger и Toothpick

Dagger генерирует код привязок и проверяет граф зависимостей при компиляции. Отсутствующие привязки и многие ошибки графа приводят к ошибке сборки. Toothpick разрешает зависимости через runtime scopes, поэтому часть ошибок конфигурации проявляется только при выполнении соответствующего сценария. Ни один из подходов сам по себе не гарантирует правильное время жизни scope и отсутствие утечек.

В legacy-фиче определите:

  • где находится composition root и кто открывает и закрывает каждый scope;
  • какие объекты общие для нескольких экранов, переживают смену конфигурации или принадлежат конкретному View;
  • как в граф попадают runtime-параметры и как проверяются отсутствующие привязки.

Не заменяйте Toothpick на Hilt механически. Сначала зафиксируйте владельцев объектов и границы scope, затем переносите по одной фиче. Проверьте создание экрана, его пересоздание, уход с экрана и выход из аккаунта, если он есть. Scope, живущий дольше своего владельца, может удерживать presenter, View или пользовательские данные, даже если зависимости успешно разрешаются.

О современном подходе на базе Dagger см. Dagger / Hilt и основы DI.

Moxy и жизненный цикл представления

Moxy реализует MVP с помощью сгенерированного кода для состояния View и делегатов. Presenter может пережить смену конфигурации и подключиться к новому View, но это не означает сохранения состояния после смерти процесса. Проверьте настройку делегатов и восстановление состояния в конкретном проекте.

Если DI создаёт presenter, выясните, кто им владеет, когда View подключается и отключается и кто освобождает подписки RxJava или отменяет асинхронную работу. Поздний callback или ошибочно удерживаемая ссылка на View могут обновить уничтоженный экран или вызвать утечку Activity / Fragment. Проверьте также, не получает ли сохранённый presenter короткоживущую зависимость от View через более долгоживущий scope.

При миграции сначала закрепите текущее поведение UI точечными тестами, выделите переиспользуемый код данных и домена, затем переводите по одному экрану на ViewModel и явный UiState, если это подходит фиче. Отдельно решите, какое состояние должно переживать смену конфигурации, а какое - смерть процесса: один ViewModel не даёт долговременного сохранения. См. Legacy & Refactoring и RxJava.