Конструктор ViewModel должен быть аннотирован с помощью @Inject вместо @AssistedInject

#java #android #viewmodel #dagger-hilt #assisted-inject

Вопрос:

Я хочу предоставить некоторую зависимость во время выполнения для ViewModel с помощью Hilt. Я последовал решению, которое было направлено d.android.com это.

 @HiltViewModel    
public class ViewViewModel extends ViewModel {
    ...
    @AssistedFactory
    public interface ViewViewModelFactory {
        ViewViewModel create(@Assisted int version);
    }

    @AssistedInject
    public ViewViewModel(ProfileRepository repository, @Assisted int version) {
        mProfileRepository = repository;
    }
}

@AndroidEntryPoint
public class CarFragment extends Fragment {
    @Inject
    ViewViewModel.ViewViewModelFactory mViewViewModelFactory;

    ...

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ViewViewModel viewModel = mViewViewModelFactory.create(21);
    }
}
 

Тем не менее, по-прежнему появляется ошибка сборки ViewModel constructor should be annotated with @Inject instead of @AssistedInject.

Я использую hilt версии 2.38.1 и AGP версии 7.0.0. Также пробовал использовать некоторые более ранние версии (2.35, 2.37).

Я также пытался создать своего собственного поставщика фабрики, но безуспешно:

 public class ViewViewModel extends ViewModel {
...
@AssistedFactory
public interface ViewViewModelFactory {
    ViewViewModel create(@Assisted int version);
}

@AssistedInject
public ViewViewModel(ProfileRepository repository, @Assisted int version) {
    mProfileRepository = repository;
}

public static ViewViewModel provideFactory(ViewViewModelFactory assistedFactory,
                             int version){
    return new ViewViewModelFactoryProvider(assistedFactory,version).create(ViewViewModel.class);
}

public static class ViewViewModelFactoryProvider implements ViewModelProvider.Factory {
    ViewViewModelFactory assistedFactory;
    int version;

    public ViewViewModelFactoryProvider(ViewViewModelFactory assistedFactory,
                                           int version) {
        this.assistedFactory = assistedFactory;
        this.version = version;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        return (T) assistedFactory.create(version);
    }
}
 

}

 @AndroidEntryPoint
public class CarFragment extends Fragment {
    @Inject
    ViewViewModel.ViewViewModelFactory mViewViewModelFactory;

    ...

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ViewViewModel viewModel = ViewViewModel.provideFactory(mViewViewModelFactory,21);
    }
 

}

Комментарии:

1. У меня та же проблема. Когда я использую @Inject ошибку, это: @Assisted parameters can only be used within an @AssistedInject-annotated constructor. . Когда я переключаюсь Inject на @AssistedInject ошибку, это: ViewModel constructor should be annotated with @Inject instead of @AssistedInject

Ответ №1:

Удалять @HiltViewModel

В ссылке, которую вы упомянули, в комментарии говорилось, что

В Dagger 2.31 этого можно достичь без использования @HiltViewModel и передачи всего вручную

Я вижу, что остальная часть реализации уже выполнена, поэтому удаление @HiltViewModel должно это сделать.

Комментарии:

1. Нет. Это создаст объект с помощью вспомогательной инъекции, но потеряет функциональность модели представления, например, сохранение состояния при изменении конфигурации. Поэтому, если мы удалим @HiltViewModel, он не будет использоваться dagger в качестве модели просмотра, вместо этого он будет использоваться как обычная фабрика.