Не в состоянии внедрить ViewModel с dagger2 Android Java - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь ввести viewmodel с помощью обычной ViewModelProviderFactory in dagger2 . (Это мое первое приложение с компонентами кинжала и архитектуры). Это ошибка, которую я получаю при создании кода.

Ошибка: (26, 10) ошибка: java.util.Map, javax.inject.Provider> не может быть предоставлен без аннотируемого метода @ Provides.

enter image description here

Вот код, который я использую

ViewModelProviderFactory

@PerActivity

public class ViewModelProviderFactory implements ViewModelProvider.Factory {

    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

    @Inject
    public ViewModelProviderFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
        this.creators = creators;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends ViewModel> T create(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);
        }
    }
}

ViewModelModule

@Module
public abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(HomeViewModel.class)
    abstract ViewModel bindHomeViewModel(HomeViewModel homeViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelProviderFactory factory);
}

ApplicationComponent

@Singleton
@Component(modules = {ApplicationModule.class, ViewModelModule.class})
public interface ApplicationComponent {

    void inject(BaseApp app);

    @ApplicationContext
    Context getContext();

    Application getApplication();

    WebService getWebService();

    PreferencesHandler getPreferencesHandler();

    InternetUtils getInternetUtils();
}

ActivityComponent

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {

    void inject(MainActivity mainActivity);

    void inject(SampleListActivity sampleListActivity);

    void inject(HomeActivity homeActivity);
}

ViewModelKey

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
public @interface ViewModelKey {
    Class<? extends ViewModel> value();
}

В моей активности я использую этот код

@Inject
ViewModelProviderFactory mViewModelFactory;
........
oncreate(){
...
homeViewModel = ViewModelProviders.of(this,mViewModelFactory).get(HomeViewModel.class);
.......
}

1 Ответ

0 голосов
/ 10 января 2019

Ваш ActivityComponent является Component (не субкомпонентом) с зависимостью от ApplicationComponent, поэтому он не имеет доступа к карте, настроенной в AppComponent.

Либо переключитесь на использование SubComponent для вашего ActivityComponent, либо обязательно включите метод обеспечения для Map<Class<? extends ViewModel>, Provider<ViewModel>> в свой AppComponent, чтобы зависимые компоненты могли получить к нему доступ.

interface AppComponent {
  // ..
  Map<Class<? extends ViewModel>, Provider<ViewModel>> creators();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...