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.+'
}
Фабричный интерфейс с методом create, который принимает параметры
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));
}
}
Модуль впрыска зарегистрирован из класса приложения
@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)
Кто-то знает, почему у Фабрики нет инициализации? Я понимаю, что модуль должен быть инициализирован, и я уверен, что модуль был вызван.
Самое заметное отличие моего кода от кода связанных вопросов заключается в том, что в вопросах конструктор помечается @Inject
не @AssistedInject
, До этой модификации я получал эту ошибку при компиляции приложения.
Ошибка: не удалось выполнить задачу ':app:compileDebugJavaWithJavac'. java.lang.ClassCastException: com.sun.tools.javac.code.Type не может быть приведен к javax.lang.model.type.DeclaredType. Кэш зависимостей dle может быть поврежден (это иногда происходит после истечения времени ожидания сетевого подключения.) Повторная загрузка Зависимости и синхронизация проекта (требуется сеть)
Состояние процесса сборки Gradle (демон) может быть повреждено. Остановка всех демонов Gradle может решить эту проблему. Остановить процессы сборки Gradle (требуется перезагрузка) Ваш проект может использовать сторонний плагин, который не совместим с другими плагинами в проекте или версией Gradle, запрошенной проектом. В случае поврежденных процессов Gradle вы также можете попробовать закрыть IDE и затем убить все процессы Java.
Может быть, это не лучший подход для достижения того, что мне нужно. Если это не так, может кто-то указать мне правильное направление?
Спасибо за вашу помощь
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));
}
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);
}
}