CustomViewdependency injection与匕首2(在活动范围内)

我的问题与此类似。

例如,我有一个LiveData实现:

 public class CustomLiveData extends LiveData<SomeEvent> { @Inject public CustomLiveData(@ActivityContext Context context) { //.... } } 

我想注入一个自定义视图:

 public class CustomView extends View { @Inject SomeApplicationProvider anyProvider; @Inject CustomLiveData dataProvider; // Getting @com.di.qualifiers.ActivityContext android.content.Context cannot be provided without an @Provides-annotated method. // @com.di.qualifiers.ActivityContext android.content.Context is injected at com.repositories.CustomLiveData.<init>(context) // com.repositories.CustomLiveData is injected at com.ui.CustomView.dataProvider com.ui.CustomView is injected at // com.di.ApplicationComponent.inject(view) public CustomView(Context context) { this(context, null); } public CustomView(Context AttributeSet attrs) { super(context, attrs); // Works ok for application provider Application.getComponent(context).inject(this); } } 

这里是DI类的其余部分:

 @ApplicationScope @Component( modules = {AndroidInjectionModule.class, ActivityBuilder.class }) public interface ApplicationComponent extends AndroidInjector<MyApp> { void inject(MyApp application); void inject(CustomView view); @Component.Builder abstract class Builder extends AndroidInjector.Builder<MyApp> { public abstract ApplicationComponent build(); } } @ActivityScope @Module (subcomponents = MainActivitySubcomponent.class) public abstract class ActivityBuilder { @Binds @IntoMap @ActivityKey(MainActivity.class) abstract AndroidInjector.Factory<? extends Activity> bindActivityInjectorFactory(MainActivitySubcomponent.Builder builder); //... } @Subcomponent(modules = {MainActivityModule.class}) public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> { @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<MainActivity> { } } @ActivityScope @Module public class MainActivityModule { @Provides @ActivityContext public Context provideActivityContext(MainActivity activity) { return activity; } // Seems to be wrong or not enough!? @Provides public CustomLiveData provideCustomLiveData(@ActivityContext Context context) { return new CustomLiveData(context); } } @Qualifier public @interface ActivityContext{ } 

请注意,如果将CustomLiveData注入到MainActivity ,则不会收到任何编译器投诉。 谢谢!

Solutions Collecting From Web of "CustomViewdependency injection与匕首2(在活动范围内)"

tl; dr不要在自定义View对象中注入模型层依赖关系

View子类不是Dagger 2注入的好目标。 View对象意味着被绘制,而不是其他,因此名称“视图”。 View的构造函数应该清楚这一点。 它们被devise用于从XML中指定的属性充注View对象。 换句话说,一个View对象应该能够在layout.xml文件中指定,在生命周期中的适当位置膨胀,然后使用findViewById(int id) , Butterknife或数据绑定来获得。 这样,最好的自定义View对象不依赖。

如果你想链接一个View和模型层的一些数据,标准模式是编写一个像RecyclerViewListView那样的Adapter。 如果这是不可能的,那么使用setter(例如setData() )比在构造函数中从模型层传递依赖关系或从View的生命周期方法之一请求注入更可取。

相反,如果使用AndroidInjector类将LiveData对象注入到Activity或Fragment中, AndroidInjector无需执行任何操作即可提供正确的Context 。 这解释了你的评论:“如果将CustomLiveData注入到MainActivity中,我不会收到任何编译器投诉。”

LiveData对象注入活动后,使用上述方法之一(适配器或setter)将数据与您的自定义View相关联。 请参阅Google Android架构示例,其中使用Dagger 2注入模型层的元素,然后使用findViewByIdsetAdapter()ListView关联。

链接到讨论注入View对象的Dagger 2问题:

https://github.com/google/dagger/issues/720

您的Dagger层次结构如下所示: appcomponent – > activitycomponent

您尝试在视图内注入活动context ,这直接依赖于appcomponent

这是不可能的,因为没有方法可以在appcomponent提供活动上下文。 相反,在内部视图中,您应该检索活动(例如使用getContext ),从中提取activitycomponent ,然后注入CustomLiveData