注入活动所需的成员

时间:2018-06-28 13:40:30

标签: java android dependency-injection dagger-2 dagger

我需要向片段中插入“ RxPermissions” RX Permissions lib实例。 它是我的(基本)片段类:

public class MapFragment extends Fragment {  
  //an empty ctor

  @Inject
  RxPermissions rxPermissions; //need inject.

  @Override
  public void onAttach(Context context) {
      AndroidSupportInjection.inject(this); //for injection
      super.onAttach(context);
  }

  @Override
  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    //When i not use injection for rxPermissions -> rxPermissions = new RxPermissions(getActivity());
    if(rxPermission.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)){
       ///TODO: implement isGranted logic
    }
  }
}

这是我的MapFragmentSubComponent和MapFragmentSubModule,用于注入MapFragment:

@Subcomponent
public interface MapFragmentSubComponent extends AndroidInjector<MapFragment> {

    @Subcomponent.Builder
    public abstract class Builder extends AndroidInjector.Builder<MapFragment>{

  }
}


@Module(subcomponents = MapFragmentSubComponent.class)
public abstract class MapFragmentSubModule {

   @Binds
   @IntoMap
   @FragmentKey(MapFragment.class)
   abstract AndroidInjector.Factory<? extends Fragment> bindMapFragmentInjectorFactory(MapFragmentSubComponent.Builder builder);

   //Contains here my provider method for example viewmodelfactory provide.

   //I need (i think) provide rxPermissions here. but how ?

  }

然后在AppComponent上使用@Component(modules = {MapFragmentSubmodule.class})安装MapFragmentSubModule

那么我如何向片段或其他注入RxPermissions? (例如活动?)

@Jeff Bowman的更新于6月29日18:39评论: 所以。我在MainActivity中注入了活动哈希(起作用),但是MapFragment中没有继承该哈希。我可以使用Dagger-android lib解决此问题吗? (或者使用旧的时尚匕首2实现方案来解决该问题?) 这是我的错误消息:

    error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)]   java.lang.Integer cannot be provided without an @Inject constructor or an @Provides-annotated method.
java.lang.Integer is injected at
.ui.main.map.MapFragment.activityHash
.ui.main.map.MapFragment is injected at
dagger.android.AndroidInjector.inject(T)
component path: .component.AppComponent ? .module.BuildersModule_BindMapFragment.MapFragmentSubcomponent

所以我需要MapFragment中MainActivityModule提供的activityHash。

1 个答案:

答案 0 :(得分:0)

如果使用dagger.android将MapFragmentSubModule包含在Activity子组件中,则您将可以在MapFragmentSubModule中访问要注入的特定Activity子类。

@Module(subcomponents = MapFragmentSubComponent.class)
public abstract class MapFragmentSubModule {
  // ...

  // You probably want @ActivityScope; see below.
  @Provides static RxPermissions provideRxPermissions(YourActivity activity) {
    return new RxPermissions(activity);
  }
}

请注意,dagger.android将只能注入您的子类YourActivity,而不能注入Activity本身。这部分是为了保持一致性:片段可以嵌套在其他Fragment内(这样,如果超类绑定是自动的,则注入Fragment将会是模棱两可的)。对于不太明确的绑定,您可能需要@Binds Activity bindActivity(YourActivity activity)

如果没有Activity子组件,则需要从Fragment中提取Activity,这意味着在Fragment子组件上安装RxPermissions。

@Subcomponent(modules = MapFragmentSubComponent.Module.class)
public interface MapFragmentSubComponent extends AndroidInjector<MapFragment> {
  @Subcomponent.Builder
  public abstract class Builder extends AndroidInjector.Builder<MapFragment> {    
  }

  @dagger.Module public abstract class Module {
    @Provides static RxPermissions provideRxPermissions(MapFragment fragment) {
      return new RxPermissions(fragment.getActivity());
    }
  }
}

也就是说,我假设您希望RxPermissions对象在Activity中保持一致,这意味着使用Activity范围的子组件(必要时创建一个子组件),并用{{1}注释您的@Provides方法}或您为活动子组件范围注释命名的任何名称。