2015-03-31 113 views
3

我正在尝试新的匕首2,这是我第一次实施它,但我无法使它工作。我想我得到的概念,我理解的例子here匕首2活动注射不工作

我尝试复制相同的结构,只是修改了我的例子。

这里是扩展图形的AppComponent,我定义了我想要的类。

@ApplicationScope 
@Component(modules = {AppModule.class, DataModule.class}) 
public interface EFAppComponent extends EFGraph { 

    /** 
    * An initializer that creates the graph from an application. 
    */ 
    public final static class Initializer { 

     private Initializer() { 
     } // No instances. 

     public static EFAppComponent init(EFApp app) { 
      return Dagger_EFAppComponent.builder() 
        .appModule(new AppModule(app)) 
        .build(); 
     } 
    } 
} 


public interface EFGraph { 

    public void inject(EFApp app); 

    public ImageLoader imageLoader(); 

    public EventBus eventBus(); 

} 

然后在每个模块中,我提供了相应的类。从这里一切正常,Dagger接缝正确构建Dagger_EFAppComponent。

然后在应用程序的I类init已使用构造

component = EFAppComponent.Initializer.init(this); 
component.inject(this); 

然后我的目标是注入ImageLoader的和EventBus在我的活动。为此,我创建一个ActivityComponent。

@ActivityScope 
@Component(
     dependencies = EFAppComponent.class, 
     modules = ActivityModule.class 
) 
public interface ActivityComponent { 

    public void inject(BaseActivity activity); 

} 

然后从我的活动我呼吁注射。

activityComponent = Dagger_ActivityComponent.builder() 
       .eFAppComponent(component) 
       .activityModule(new ActivityModule(this)) 
       .build(); 
activityComponent.inject(this); 

所以,因为我在应用程序注入注入方法调用之后在我的活动中声明了@Inject EventBus eventBus。那不是。

因此,在逐步调试和跟踪我的应用程序和示例后,我意识到Dagger_ActivityComponent未正确构建。

private final ActivityModule activityModule; 
    private final EFAppComponent eFAppComponent; 

    private Dagger_ActivityComponent(Builder builder) { 
     assert builder != null; 
     this.activityModule = builder.activityModule; 
     this.eFAppComponent = builder.eFAppComponent; 
     initialize(); 
    } 

如果initialize方法是空的,并且没有Provider被声明为变量。

我错过了什么吗?我一整天都在试图让它工作,但我不是成功的。

欣赏帮助。

回答

14

好吧......花了一整天的时间后,我决定发布它,5分钟后我找到了解决方案。

我对我的所有活动都使用了BaseActivity,并且我认为我可以使用它来注入我的组件,但接缝不可行。

所以我只是在我的ActivityComponent改变这一行

public void inject(BaseActivity activity) 

public void inject(MainActivity activity) 

因此,要在那里我注射的依赖性活动的名称...

什么给我带来了一个新问题。我如何实现一个基础组件来处理我所有的活动?或者我必须为每个视图/活动/片段创建一个组件我想拥有DI?

+0

您应该创建另一个问题,我认为或修改现有的 – 2015-03-31 13:04:48

+0

我会创建一个新的,所以如果人们面临同样的问题,这里是一个解决方案hehe – Marcel 2015-03-31 13:24:32

+2

在同一个组件'public void inject(SecondActivity activity)'' 。这是由于匕首提供的静态输入。 – 2015-03-31 13:33:48

2

@Marcel,我最近将一个项目从Dagger 1.2迁移到2.0。我有类似的解决方案,其中抽象的BaseActivity通过沿着“application.inject(this);”的方式执行某些操作来注入依赖项。在Dagger 2.0中,这是不可能的(截至目前),如上面评论中所述。

我解决这个问题的方法之一是通过改变Application类本身的“inject”方法来强类型化对象。例如..

class MyApp extends Application { 
    ... 
    public void inject(Object activity) { 
    if (activity instanceof MainActivity) { 
     mComponent.inject((MainActivity) activity); 
    } else if (activity instanceof SubActivity) { 
     mComponent.inject((SubActivity) activity); 
    } 
    } 
} 

因此,我不必改变我现有的类中的任何东西。

供参考:@ thomas-broyer有一个名为Bullet的项目也是这样做的。