使用Roboguice无法正常工作的Android辅助注入

时间:2016-05-18 08:26:04

标签: java android dependency-injection roboguice assisted-inject

我正在尝试在构造函数中传递一些参数时注入一些类。为了实现这一点,我发现这些问题(12)说这可以通过使用辅助注射与工厂来实现。这是我的代码的样子,按照提供的示例和阅读相关文档后的一些修改。

gradle script

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));
    }
}

从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)

有人知道为什么工厂没有初始化?我明白应该由模块初始化,我确信它已被调用的模块。

我的代码与链接问题中的代码之间最可重复的区别在于,在问题中,构造函数使用@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 个答案:

    答案 0 :(得分:0)

    最后,我通过在Application类中添加RoboGuice.setUseAnnotationDatabases(false)来使其工作:

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

    答案 1 :(得分:0)

    AssistedInjectnot supported for Roboguice 3+

    我很高兴您可以通过禁用AnnotationsDatabase来解决问题。您之前的错误:

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

    是在签名中使用原始类型的构造函数上使用@Inject时发生的。见this answer

    允许您使用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);
        }
    }