Инъекция с помощью Android с Factory с использованием Roboguice не работает

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

скрипт Gradle

dependencies { 
    compile 'org.roboguice:roboguice:3.+'
    provided 'org.roboguice:roboblender:3.+'
    compile 'com.google.inject.extensions:guice-assistedinject:3.+' 
}

Заводской интерфейс с методом создания, принимающим параметры

public interface ICustomObjectFactory {
    ICustomObject create(Callback callback);
}

Класс, реализующий интерфейс

public class CustomObject implements ICustomObject {
    protected String name;

    @AssistedInject
    public CustomObject(@Assisted Callback callback){
       this.callback = callback;
    }
}

Модуль, используемый и вызываемый из класса Aplication

public class SomeModule extends Module {

    @Override
    protected void configure() {
         install(new FactoryModuleBuilder()
            .implement(ICustomObject.class, CustomObject.class)
            .build(ICustomObjectFactory.class));
    }
}

Модуль инъекции зарегистрирован из класса Application

@Override
public void onCreate() {
    super.onCreate();

    RoboGuice.getOrCreateBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE,
            RoboGuice.newDefaultRoboModule(this), new SomeModule(this));
}

Использование фабрики

public class SomeClass implements Callback {

    @Inject ICustomObjectFactory factory;

    public SomeClass () {
        ICustomObject first = this.factory.create(this);
    }
}

При всем таком, я получаю эту ошибку, когда пытаюсь использовать фабрику, поскольку она использовалась в SomeClass

java.lang.IllegalStateException: Factories.create() factories cannot be used until they're initialized by Guice.
        at com.google.inject.internal.util.$Preconditions.checkState(Preconditions.java:142)
        at com.google.inject.assistedinject.FactoryProvider2.getBindingFromNewInjector(FactoryProvider2.java:564)
        at com.google.inject.assistedinject.FactoryProvider2.invoke(FactoryProvider2.java:625)
        at java.lang.reflect.Proxy.invoke(Proxy.java:397)
        at $Proxy12.create(Unknown Source)

Кто-нибудь знает, почему Factory не инициализирован? Я понимаю, что это должно быть инициализировано модулем, и я уверен, что модуль был вызван.

Самая заметная разница между моим кодом и кодом из связанных вопросов заключается в том, что в вопросах конструктор помечен @Inject, а не @AssistedInject. До этой модификации я получал эту ошибку при компиляции приложения.

Error:Execution failed for task ':app:compileDebugJavaWithJavac'. java.lang.ClassCastException: com.sun.tools.javac.code.Type cannot be cast to javax.lang.model.type.DeclaredType dle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.) Re-download dependencies and sync project (requires network)

  • Состояние процесса сборки Gradle (демона) может быть повреждено. Эту проблему может решить остановка всех демонов Gradle. Остановить процессы сборки Gradle (требуется перезапуск)
  • В вашем проекте может использоваться сторонний плагин, который несовместим с другими плагинами в проекте или с версией Gradle, запрошенной проектом.
  • In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.

    Может быть, это не лучший подход для достижения того, что мне нужно. Если нет, может ли кто-нибудь указать мне правильное направление?

    Спасибо за вашу помощь


    person Jofre Mateu    schedule 18.05.2016    source источник


    Ответы (2)


    В конце я заставляю его работать, добавляя RoboGuice.setUseAnnotationDatabases(false) в класс Application:

    @Override
    public void onCreate() {
        super.onCreate();
    
        RoboGuice.setUseAnnotationDatabases(false);
        RoboGuice.getOrCreateBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE,
                RoboGuice.newDefaultRoboModule(this), new SomeModule(this));
    }
    
    person Jofre Mateu    schedule 23.05.2016

    AssistedInject не поддерживается для Roboguice 3+

    Я рад, что вы смогли заставить его работать с отключением AnnotationsDatabase. Ваша предыдущая ошибка:

    com.sun.tools.javac.code.Type cannot be cast to javax.lang.model.type.DeclaredType
    

    возникло из-за использования @Inject в конструкторе с примитивными типами в сигнатуре. См. этот ответ

    Простое решение, которое должно позволить вам использовать AnnotationsDatabase, - это использовать Provider<T>, который, в отличие от AssistedInject, поддерживается в Roboguice 3+. Итак, в модуле:

    binder.bind(CustomObject.class).toProvider(CustomObjectProvider.class);
    

    затем введите в Provider таким образом:

    public class CustomObjectProvider implements Provider<CustomObject> {
    
        Callback callback;
    
        @Inject
        public CustomObjectProvider(Callback callback) {
            this.callback = callback;
        }
    
        @Override
        public CustomObject get() {
            return new CustomObject(callback);
        }
    }
    
    person David Rawson    schedule 04.08.2016