You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Dagger2注入后字段为null?如何正确实现对象注入?

问题分析与解决方案

你的问题核心在于手动创建了Presenter实例,跳过了Dagger的字段注入流程,同时混淆了构造函数注入和字段注入的正确使用方式。咱们一步步拆解问题,然后给出靠谱的实现方案。

为什么Context会是Null?

先看你的MyModule代码:

@Module
class MyModule {
  @Provides
  MyPresenter provideMyPresenter(MyView view) {
    return new MyPresenter(view);
  }
}

这里你直接new MyPresenter(view),相当于把对象创建的控制权从Dagger手里抢过来了——Dagger只会对它自己创建的对象执行字段注入操作。你手动new出来的实例,Dagger根本不知道它的存在,自然不会帮你注入Context字段,这就是空指针的根源。

另外,你的MyPresenter已经标注了@Inject构造函数,这时候其实完全不需要在Module里写@Provides方法,Dagger可以自动通过构造函数创建实例,前提是你得让Dagger接管创建过程。

正确的实现步骤

第一步:修正Presenter的注入逻辑

保留@Inject构造函数,确保Dagger能通过构造函数创建实例,同时处理Context依赖:

class MyPresenter {
  @Inject Context context;
  private MyView view;

  // 让Dagger通过这个构造函数创建实例,自动注入MyView
  @Inject
  MyPresenter(MyView view) {
    this.view = view;
  }
}

第二步:精简Module,只提供Dagger无法自动生成的依赖

因为Presenter已经有@Inject构造函数,MyModule里不需要再写provideMyPresenter了。只需要提供Dagger无法自动获取的依赖(比如Context、MyView):

@Module
class MyModule {
  // 提供ApplicationContext,避免持有Activity引用导致内存泄漏
  @Provides
  Context provideContext(MyActivity activity) {
    return activity.getApplicationContext();
  }

  // 提供MyView实例(假设MyActivity实现了MyView接口)
  @Provides
  MyView provideMyView(MyActivity activity) {
    return activity;
  }
}

第三步:配置Component关联Module和注入目标

你的Component需要关联Module,并且声明对Activity的注入方法:

@Component(modules = MyModule.class)
interface MyActivityComponent {
  void inject(MyActivity activity);
}

第四步:在Activity中完成正确注入

保持Activity的注入逻辑,注意使用Dagger自动生成的Component类(格式为DaggerXXXComponent):

class MyActivity extends Activity implements MyView {
  @Inject MyPresenter presenter;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 让Dagger创建Component并完成注入
    DaggerMyActivityComponent.create().inject(this);
    // 现在presenter和presenter.context都应该不为null了
  }
}

关键知识点:构造函数注入 vs 字段注入

  • 构造函数注入:这是Dagger最推荐的方式,依赖通过构造函数传入,对象创建时就完成依赖注入,从根源避免空指针。只要构造函数加@Inject,Dagger会自动寻找所需依赖来创建实例。
  • 字段注入:一般用于系统创建的类(比如Activity、Fragment),这些类的实例不由我们控制,只能用字段注入。但对于你自己写的业务类(比如Presenter),优先用构造函数注入更稳妥。

如果非要在Presenter里用字段注入Context,核心前提还是得让Dagger来创建Presenter实例——去掉Module里的手动创建逻辑,Dagger会自动完成构造函数注入+字段注入的全套流程。


内容的提问来源于stack exchange,提问作者David Medenjak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:55:19