Создание экземпляров ViewModels напрямую, без использования метода ViewModelProviders.of

У меня есть ViewModel под названием RecipesViewModel. Обычно я создавал его таким образом:

RecipesViewModel viewModel = ViewModelProviders.of(this, new ViewModelProvider.Factory() {
            @Override
            public <T extends ViewModel> T create(Class<T> modelClass) {
                return (T) new RecipesViewModel(recipesRepository);
            }
        }).get(RecipesViewModel.class);

Но теперь я использую dagger2, поэтому я поместил аннотацию @Inject в конструктор этой ViewModel, чтобы я мог вставить ее прямо в свой фрагмент, используя инжектор поля.

Мой вопрос: я что-то потеряю, запустив модель просмотра таким образом, а не ViewModelProviders.of? Моя ViewModel уже имеет область видимости, поэтому в контексте создается только один экземпляр.

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

-- РЕДАКТИРОВАТЬ --

Читая документацию android.arch.lifecycle.ViewModel, боюсь немного больше. Где использовать ViewModelProviders.of для предоставления области действия (фрагмента или действия). Если я создам его напрямую, что будет с областью действия?

ViewModel - это класс, который отвечает за подготовку и управление данными для действия или фрагмента. Он также обрабатывает связь Activity / Fragment с остальной частью приложения (например, вызывает классы бизнес-логики).

ViewModel всегда создается в связи с областью видимости (фрагментом или действием) и сохраняется, пока существует область видимости. Например. если это действие, до его завершения.

Другими словами, это означает, что ViewModel не будет уничтожен, если его владелец будет уничтожен для изменения конфигурации (например, вращения). Новый экземпляр владельца просто повторно подключится к существующей ViewModel.

-- /РЕДАКТИРОВАТЬ --

Код RecipesViewModel показан ниже:

@PerActivity
public class RecipesViewModel extends ViewModel {
    private static final String TAG = "RecipesViewModel";
    private final RecipesRepository recipesRepository;

    private LiveData<List<Recipe>> recipes = null;

    @Inject
    public RecipesViewModel(RecipesRepository recipesRepository) {
        this.recipesRepository = recipesRepository;
    }

    public final void loadAll() {
        recipes = recipesRepository.getRecipes();
    }

    public LiveData<List<Recipe>> getRecipes() {
        return recipes;
    }
}

person alexpfx    schedule 03.07.2017    source источник
comment
Без экспериментов и только чтения документации и того, что я знаю об архитектурных компонентах, все сводится к тому, как вы управляете областью действия. Если, например, при изменении конфигурации вы создаете новый компонент кинжала, то модель представления, предоставляемая этим компонентом, определенно будет отличаться от той, которая была у вас раньше, потому что области видимости привязаны к компонентам. Из документации я понял, что этого не произойдет, если вы используете ViewModelProviders.of. Этого также не произойдет до тех пор, пока компонент кинжала будет одинаковым - предоставленная модель просмотра также такая же.   -  person Fred    schedule 03.07.2017
comment
ViewModelProviders предоставляет хранилище, которое ограничено текущим действием или фрагментом и передается следующему экземпляру при изменении конфигурации. Если вместо этого вы объявляете свою ViewModel как глобальный синглтон, это может вызвать проблемы, потому что состояние будет разделяться между различными экземплярами действий или фрагментов, а также ViewModel не будет уничтожен с помощью Activity или Fragment.   -  person BladeCoder    schedule 08.09.2017


Ответы (1)


Для меня прямо сейчас (и мне нужно исследовать это), но внедрение модели представления вместо использования функциональности ViewModelProviders означает, что вы теряете простую связь между фрагментами активности.

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

person Daniel Wilson    schedule 29.11.2017