#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 в качестве модели просмотра, вместо этого он будет использоваться как обычная фабрика.