Android 使用 Roboguice 的 Factory 辅助注入不起作用

Android assisted injection with Factory using Roboguice not working

我试图在构造函数中传递一些参数时注入一些 classes。为了实现这一目标,我发现了这个问题 (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);
}

Class 实现接口

public class CustomObject implements ICustomObject {
    protected String name;

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

从应用程序使用和调用的模块class

public class SomeModule extends Module {

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

从应用程序注册的注入模块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)

有人知道为什么 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)

  • The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem. Stop Gradle build processes (requires restart)
  • Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
  • In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.

    也许这不是实现我所需的最佳方法。如果不是,有人能给我指出正确的方向吗?

    谢谢大家的帮助

    最后,我通过在应用程序 class:

    中添加 RoboGuice.setUseAnnotationDatabases(false) 使其工作
    @Override
    public void onCreate() {
        super.onCreate();
    
        RoboGuice.setUseAnnotationDatabases(false);
        RoboGuice.getOrCreateBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE,
                RoboGuice.newDefaultRoboModule(this), new SomeModule(this));
    }
    

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