У меня проблемы с внедрением зависимости в мою модель представления. Я продолжаю получать Невозможно создать экземпляр класса ....viewModel.UserProfileViewModel. Я пытался разобраться в этом вопросе. Любые предложения будут действительно оценены. Вот мой код. В других вопросах я видел, что это обычно вызвано наличием параметра в конструкторе модели представления, и создание фабрики должно решить проблему. но, похоже, это не сработало для меня. Я должен что-то упустить.
Спасибо!
App component:
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, ViewModelModule.class})
public interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
ApplicationComponent build();
}
}
=====================================================
App module:
@Module
public class AppModule {
Application mApplication;
public AppModule(Application application){
mApplication = application;
}
@Provides
@Singleton
Application providesApplication(){
return mApplication;
}
}
===========================================================
ViewFactory
@Singleton
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) {
this.creators = viewModels;
}
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
===========================================================
View key
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
========================================================
View Module
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(UserProfileViewModel.class)
abstract ViewModel bindUserViewModel(UserProfileViewModel userViewModel);
}
===========================================================
view model class
public class UserProfileViewModel extends ViewModel {
private UserRepository mUserRepository;
private LiveData<User> mObservableUser;
@Inject
public UserProfileViewModel(@NonNull UserRepository userRepo){
this.mUserRepository = userRepo;
}
public void init(String userId){
if (this.mObservableUser != null) {
return;
}
mObservableUser = mUserRepository.getUser(userId);
}
public LiveData<User> getUser() {
return this.mObservableUser;
}
}
====================================================
in fragment
viewModel = ViewModelProviders.of(this, viewModelFactory).get(UserProfileViewModel.class);
viewModel.init(mUserId);
Откуда должен взяться
App component:
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, ViewModelModule.class})
public interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
ApplicationComponent build();
}
}
=====================================================
App module:
@Module
public class AppModule {
Application mApplication;
public AppModule(Application application){
mApplication = application;
}
@Provides
@Singleton
Application providesApplication(){
return mApplication;
}
}
===========================================================
ViewFactory
@Singleton
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) {
this.creators = viewModels;
}
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
===========================================================
View key
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
========================================================
View Module
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(UserProfileViewModel.class)
abstract ViewModel bindUserViewModel(UserProfileViewModel userViewModel);
}
===========================================================
view model class
public class UserProfileViewModel extends ViewModel {
private UserRepository mUserRepository;
private LiveData<User> mObservableUser;
@Inject
public UserProfileViewModel(@NonNull UserRepository userRepo){
this.mUserRepository = userRepo;
}
public void init(String userId){
if (this.mObservableUser != null) {
return;
}
mObservableUser = mUserRepository.getUser(userId);
}
public LiveData<User> getUser() {
return this.mObservableUser;
}
}
====================================================
in fragment
viewModel = ViewModelProviders.of(this, viewModelFactory).get(UserProfileViewModel.class);
viewModel.init(mUserId);
?