2017-01-25 7 views
3

У меня есть Android-активность, в которой я использую Dagger2 для ввода презентатора. Я бы хотел, чтобы мой Ведущий был способен удерживать состояние, даже если происходит изменение конфигурации.Цели Dagger2 и жизненный цикл активности

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

Я получаю сработало, потому что, если я раскрываю экземпляр Presenter для жизни Деятельности, то нет ли шанса, что Presenter будет собирать мусор, когда Activity переходит через onDestroy() во время изменения конфигурации? Моя другая мысль заключалась в том, чтобы использовать область действия, которая действительна в течение срока действия приложения. Однако, если я это сделаю, как я могу гарантировать, что мой Ведущий может быть собран мусором после того, как активность была уничтожена навсегда (не из-за изменения конфигурации, но что-то вроде нажатия на кнопку возврата)?

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

ответ

4

Я бы настоятельно советовал не пытаться реализовать этот подход.

Вы эффективно пытаетесь использовать каркас DI, чтобы поддерживать конкретный поток жизненного цикла, хотя рамки DI не предназначены для использования таким образом.

Недавно я ответил another similar question, в котором ОП попытался делить состояние в View-Model между разными Activities. Хотя варианты использования не идентичны, общий шаблон один и тот же - попытка делегировать обязанности по контролю потока в рамки DI, что не является хорошей идеей.

Лучшим подходом в вашем случае (IMHO) было бы сохранение текущего состояния перед вращением, повторное создание презентатора при вращении, а затем восстановление его состояния.

Как сохранить состояние во время вращения зависит от того, что именно вы пытаетесь сохранить:

  • Если вам нужно сохранить связанные UI состояния (выбор, тексты, положение элементов и т.д.), то вы могут использовать обычные обратные вызовы onSaveInstanceState() и onRestoreInstanceState()
  • Если вам необходимо сохранить определенное состояние бизнеса (текущие сетевые запросы, данные, изменения данных и т. д.), тогда инкапсулируйте эту логику в бизнес-классе (например, SomeBusinessUseCaseManager) и введите этот класс из Application широкий компонент с прицелом.

Подробный обзор областей применения Dagger here.

Подробнее о DI на Android можно найти here.

+0

Ваша вторая рекомендация похожа на то, что я делаю с моим Ведущим. У Presenter есть несколько UseCases, введенных в него (я создаю экземпляры UseCase в Activity и вставляя в Presenter using конструктор). Если я переношу экземпляр UseCase в компонент, который живет в течение всего срока действия приложения, то UseCase может продолжать работать во время конфигурации. изменение и когда после конфигурации создается новый презентатор (область действия). измените его, будут введены уже запущенные прецеденты. Это решает проблему необходимости повторить то, что уже было начато. – neonDion

+0

@neonDion, звучит как сплошной план. Обратите внимание, что если вы сделаете это, вы получите дополнительное преимущество, чтобы выйти из докладчиков и абстрагироваться от связанных с сетью материалов. Это большой шаг к развязанной конструкции. – Vasiliy

0

Согласно этой статье о пользовательском Скоупсе:

http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/

Короче - телескопы дают нам «местные одиночка», которые живут до тех пор, как сам объем.

Просто, чтобы быть чистым - нет @ActivityScope или @ApplicationScope аннотации, предоставленные по умолчанию в кинжале 2. Это просто обычное использование пользовательских областей. По умолчанию доступна только @Singleton область (предоставляемая самой Java), а точка с использованием области не достаточно (!), И вам нужно позаботиться о компоненте, который содержит эту область. Это означает сохранение ссылки на него в классе Application и повторное использование его при изменении Activity.

public class GithubClientApplication extends Application { 

    private AppComponent appComponent; 
    private UserComponent userComponent; 

    //... 

    public UserComponent createUserComponent(User user) { 
     userComponent = appComponent.plus(new UserModule(user)); 
     return userComponent; 
    } 

    public void releaseUserComponent() { 
     userComponent = null; 
    } 

    //... 
} 

Вы можете посмотреть на этом примере проекта может:

http://github.com/mmirhoseini/marvel

и эту статью:

https://hackernoon.com/yet-another-mvp-article-part-1-lets-get-to-know-the-project-d3fd553b3e21

, чтобы получить больше знакомы с MVP и узнать, как кинжалом объем работает.

+0

У вас есть много информации в ваших ссылках. Можете ли вы добавить краткий обзор в своем ответе, который отвечает на вопрос: есть ли способ гарантировать, что мой Ведущий переживет изменение конфигурации Activity, а также не будет просочиться в течение срока действия приложения? – neonDion

+0

Хорошо, тогда я отредактирую ответ, но, по крайней мере, посмотрю на это, потому что необходимо знать, что области являются всего лишь тегом и, к сожалению, они ничего не делают, и вам нужно обрабатывать все: http: // frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/ –

 Смежные вопросы

  • Нет связанных вопросов^_^