如何使用AndroidInjector在模块内部获取MainActivity [英] How to get MainActivity inside a module using AndroidInjector

查看:100
本文介绍了如何使用AndroidInjector在模块内部获取MainActivity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

With dagger-android one now can simply write the following and successfully inject the app's dependencies:

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

一个非常简单的例子。基本上将所有内容连接起来,以便能够通过注入正确的片段管理器来获取对象任何内容。可以,而且可以。

A very trivial example. Basically wire up everything to be able to get the object Whatever with the correct fragment manager injected. This is ok and works.

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

However, what if I want to use the main activity inside a module? Say I want to actually make Whatever explicitly expose the dependency to the fragment manager by changing the constructor argument:

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

我现在需要提供这种依赖性。怎么办呢?因此,我尝试了以下操作:

I now need to provide this dependency. How does one go about it? So I've tried the following:

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

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

现在匕首抱怨称找不到 @Providers MainActivity 。我认为 @ContributesAndroidInjector 方法将能够提供活动。我对第一种情况下注入依赖项没有问题感到困惑,但是现在它不能做到。

Now dagger complains that it cannot find a @Providers for the MainActivity. I thought the @ContributesAndroidInjector method would be able to provide the activity. I'm also a bit puzzled as to how it has no problem injecting the dependency in the first case, but now it cannot do it.

我也尝试过为此建立一个工厂,就像这样:

I've also tried to build a factory for this, something like:

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

最终会出现相同的错误。

Which ends up in the same error.

有人能做到吗??在它变得非常简单之前,只需使用 MainActivity 的实例构建模块,然后将其存储在字段中并提供该模块即可。现在……一切都在幕后。

Has anyone managed to do this?? Before it was pretty easy, one would just build the module with the instance of the MainActivity store it in a field and provide that. Now... everything happens behind the curtains.

将非常感谢!

推荐答案

在我的设置中,我在 sub-di-packages di / 软件包。 >在我的 ui / 包中。在 ui / di 包中,我声明了以下模块和组件:

In my setup I have a di/ package in the root of sub-di-packages in my ui/ package. In the ui/di package I have declared the following module and component:

@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> {
    }
}

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

on the top-level di package where I keep my ApplicationComponent, I have an additional module

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

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

}

您可以想象 BuildersModule @Component(modules = { ApplicationComponent 的一部分)。

And as you can imagine BuildersModule, is part of @Component(modules = { of ApplicationComponent.

免责声明:

我对dagger2还是很陌生,但我仍在尝试找出很多东西。可能有更好的方法来满足您的需要。

Disclaimer: I am fairly new to dagger2 and I am still try to figure out a lot of stuff. There may be better ways to achieve what you need.

这篇关于如何使用AndroidInjector在模块内部获取MainActivity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆