【问题标题】:Dagger 2 injection returning nullDagger 2 注入返回 null
【发布时间】:2015-08-13 20:02:19
【问题描述】:

这是我的申请文件

private AppComponent component;

@Override
public void onCreate() {
    super.onCreate();
    setupGraph();
}

private void setupGraph() {
    component = DaggerAppComponent.builder()
            .appModule(new AppModule(this))
            .build();
    component.inject(this);
}

public AppComponent component() {
    return component;
}

应用组件:

@Singleton
@Component(
    modules = {
        AppModule.class
    }
)
public interface AppComponent {
    void inject(BaseActivity activity);

    void inject(BaseFragment fragment);
}

活动模块:

@Module public final class ActivityModule {

private final Activity activity;

public ActivityModule(Activity activity) {
    this.activity = activity;
}

@Provides @ActivityContext
public Context provideActivityContext() {
    return activity;
}

/**
 * Expose the activity to dependents in the graph.
 */
@Provides @PerActivity
Activity activity() {
    return this.activity;
}

@Provides @GetFragmentManager
public FragmentManager provideFragmentManager() {
    return ((BaseActivity)activity).getSupportFragmentManager();
}

活动组件:

@PerActivity
@Component(dependencies = AppComponent.class, modules = {ActivityModule.class, PresenterModule.class})
public interface ActivityComponent {
    //Exposed to sub-graphs.
    Activity activity();
}

我正在像这样在我的 BaseActivity 中进行注入

((MyApplication) getApplication()).component().inject(this)

不确定这种注入是否正确,但我没有收到编译错误。

现在,当我试图访问我的片段中的演示者时,问题就来了,因为它是空的。我将我的演示者模块定义如下

演讲者模块: 1. 第一次尝试

@Module
public class PresenterModule {

    @Provides @PerActivity
    public Presenter accessPresenter(MyPresenter presenter){
        return presenter;
    }
}
  1. 第二次尝试

    @模块 公共类 PresenterModule {

    @Provides @PerActivity
    public Presenter accessPresenter(){
        return new MyPresenter();
    }
    

    }

在我的片段中我正在做

@Inject MyPresenter presenter;

在我的 onViewCreated 上,我试图将视图设置为

presenter.setView(this); // This is null

MyPresenter 与 EffectiveAndroidUI 类似,唯一的区别是我的构造函数中没有任何内容。

【问题讨论】:

  • 希望您在 Android Manifest 文件中添加了应用程序类名称。没有它,应用程序将工作,但匕首组件将为空。

标签: java android dagger-2


【解决方案1】:

听起来你没有注入你的片段。当您使用@Inject 注释成员时,您还必须调用yourObjectGraph.inject(this),其中注入方法的签名如下:

void inject(YourFragmentClass fragment);

您有两种选择可以让您的演示者访问您的片段。将此方法添加到您的应用程序组件并在您的 onCreate() 函数中调用它。或者在创建片段时将其传递给演示者。 例如:

YourFragmentClass newInstance(Bundle savedInstance, YourPresenter presenter) {
     ...
}

【讨论】:

  • 我认为这是 Dagger1 的要求.. 因为对象图在 dagger 2 中已被弃用。
  • 不完全是,您调用您在组件接口中定义的inject(...) 方法来实现依赖关系。它本质上是创建一个对象图。唯一的区别是你在 Dagger 2 中定义了 inject 方法,而它已经在 Dagger 1 中定义了。只需将 inject 方法添加到你的应用程序组件中,你就可以在你的 Fragment 上调用inject(...)
  • baseFragment 不会满足这个要求。现在我正在注入我的 BaseFragment 就像我的 baseActivity ((BaseActivity) getActivity()).getApplicationComponent().inject(this);
  • 当你在一个类上调用inject(...) 时,Dagger 只能注入该类本身及其超类的成员。 Dagger 不知道您要在派生类中注入的成员,因为您的基类也不知道。
  • 有趣..谢谢这个工作..但是有没有更好的方法来做到这一点..就像我只是注入我的基类,它也可以注入我的派生类。
【解决方案2】:

您需要像接口一样引用您的演示者:

@ActivityScope @Component(dependencies = ApplicationComponent.class,
modules = { GenreModule.class })
public interface GenreFragmentComponent {
  void inject(GenreFragment genreFragment);
  GenrePresenter getPresenter(); // Like this
}

这里的完整示例:https://github.com/ppamorim/Amazing-MVP

【讨论】:

  • 为什么需要将presenter作为接口?
  • Presenter 不是一个接口,这是 Presenter 的“参考”。否则:Dagger 1 理解起来有点复杂。我建议你从 Dagger 2 开始。没有反射,一个简单的预处理器。很多好处。
【解决方案3】:

在我的例子中,我将一个类注入到一个片段而不是它的演示者,然后更正它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 2018-06-13
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多