如何使用 AndroidInjector 在模块中获取 MainActivity

How to get MainActivity inside a module using AndroidInjector

使用 dagger-android 现在可以简单地编写以下内容并成功注入应用程序的依赖项:

@Module
public abstract class MainActivityModule {
  @ContributesAndroidInjector
  abstract MainActivity contributesMainActivity();
}

@Singleton
@Component(modules = {
    AndroidSupportInjectionModule.class,
    AndroidInjectionModule.class,
    AppModule.class,
    MainActivityModule.class
})
public interface ApplicationComponent {
  void inject(BaseApplication baseApplication);

  @Component.Builder
  interface Builder {
    @BindsInstance
    Builder application(Application application);

    ApplicationComponent build();
  }
}

@Module
public abstract class AppModule {}

public class MainActivity extends AppCompatActivity implements 
  HasSupportFragmentInjector {
  @Inject
  DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
  @Inject
  Whatever whatever;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    AndroidInjection.inject(this);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

  @Override
  public AndroidInjector<Fragment> supportFragmentInjector() {
    return dispatchingAndroidInjector;
  }
}


public class BaseApplication extends Application implements 
  HasActivityInjector {
  @Inject
  DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

  @Override
  public AndroidInjector<Activity> activityInjector() {
    return dispatchingAndroidInjector;
  }

  @Override
  public void onCreate() {
    DaggerApplicationComponent.builder()
            .application(this)
            .build()
            .inject(this);
    super.onCreate();
  }
}

public class Whatever {
   private final FragmentManager fragmentManager;

   @Inject
   Whatever(MainActivity mainActivity) {
    this.fragmentManager = mainActivity.getSupportFragmentManager();
   }
}

一个非常简单的例子。基本上连接所有东西,以便能够通过注入正确的片段管理器来获取对象 Whatever。这没问题并且有效。

但是,如果我想在模块中使用 main activity 怎么办?假设我实际上想通过更改构造函数参数 Whatever 显式地将依赖项公开给片段管理器:

@Inject
Whatever(FragmentManager fragmentManager) {...}

我现在需要提供这个依赖项。如何去做呢?所以我尝试了以下方法:

@Module
public abstract class MainActivityModule {
  @ContributesAndroidInjector
  abstract MainActivity contributesMainActivity();

  @Provides
  static FragmentManager providesFragmentManager(MainActivity activity) {
     return activity.getSupportFragmentManager();
  }
}

现在 dagger 抱怨它无法为 MainActivity 找到 @Providers。我认为 @ContributesAndroidInjector 方法能够提供 activity。我也有点疑惑,第一种情况下注入依赖没有问题,但现在却做不到。

我也试过为此建立一个工厂,比如:

public FragmentManagerFactory {
   private final FragmentManager fm;

   @Inject
   FragmentManagerFactory(MainActivity mainActivity){
     this.fm = mainActivity.getSupportFragmentManager();
   }

   public FragmentManager get() {
     return fm;
   }
}

@Module
public abstract class MainActivityModule {
  @ContributesAndroidInjector
  abstract MainActivity contributesMainActivity();

  @Provides
  static FragmentManager providesFragmentManager(FragmentManagerFactory fragmentManagerFactory) {
     return fragmentManagerFactory.get();
  }
}

最终出现同样的错误。

有人成功做到了吗??在它变得非常简单之前,人们只需使用 MainActivity 的实例构建模块,将其存储在一个字段中并提供它。现在……一切都在幕后发生。

非常感谢您的帮助!

在我的设置中,我的 ui/ 包中 sub-di-packages 的根目录中有一个 di/ 包。在 ui/di 包中,我声明了以下模块和组件:

@dagger.Module
public class MainActivityModule {
   @Provides
   FragmentManager provideFragmentManager(MainActivity mainActivity) {
    return mainActivity.getSupportFragmentManager();
   }
}

MainActivitySubcomponent

@Subcomponent(modules = MainActivityModule.class)
public interface MainActivitySubcomponent  extends AndroidInjector<MainActivity> {

    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {
    }
}

在我保存 ApplicationComponent 的顶级 di 包中,我还有一个额外的 module

@Module(subcomponents = {MainActivitySubcomponent.class })
public abstract class BuildersModule {

   @Binds
   @IntoMap
   @ActivityKey(MainActivity.class)
   abstract AndroidInjector.Factory<? extends Activity> mainActivityBinder(MainActivitySubcomponent.Builder builder);

}

正如您想象的那样,BuildersModuleApplicationComponent@Component(modules = { 的一部分。


免责声明: 我是 dagger2 的新手,我仍在尝试弄清楚很多东西。可能有更好的方法来实现您的需求。