Dagger2 Android构造函数注入时出现空指针异常求助
嘿,我来帮你排查这个空指针问题,同时聊聊MVP模式下非Activity类获取Context的最优实践~
一、先排查空指针的核心原因
你遇到的空指针大概率是以下几个问题之一:
- Component初始化时没传入有效Context
你需要确保ContextModule的实例是用Application Context(而非Activity Context)初始化的,并且Component构建时正确关联了这个Module。 - Interactor是手动new出来的,而非Dagger创建
如果你自己new MyInteractor(),Dagger根本没机会为它注入Context,自然会是空指针。必须通过Dagger提供的方法获取Interactor实例。 - Interactor的注入配置不完整
要么没给Interactor的构造函数加@Inject注解,要么Component里没声明提供Interactor的方法。
二、正确的Dagger注入示例
我补全你的代码并给出标准实现:
1. 完善ContextModule(你的基础代码没问题,建议明确返回Application Context)
@Module public class ContextModule { private final Context appContext; public ContextModule(Context context) { // 确保传入的是Application Context,避免内存泄漏 this.appContext = context.getApplicationContext(); } @Singleton @Provides public Context provideContext() { return appContext; } }
2. 完善Component
@Singleton @Component(modules = {ContextModule.class}) public interface AppComponent { // 提供获取Context的方法(可选,直接注入Interactor更常用) Context context(); // 提供Interactor的实例,或者声明注入方法 MyInteractor provideMyInteractor(); }
3. Interactor使用构造注入
public class MyInteractor { private final Context mContext; // 必须加@Inject注解,让Dagger识别这个构造函数 @Inject public MyInteractor(Context context) { this.mContext = context; } // 业务方法示例 public void loadLocalData() { // 安全使用mContext,比如访问SharedPreferences SharedPreferences sp = mContext.getSharedPreferences("data", Context.MODE_PRIVATE); // ... } }
4. 在Application中初始化Component
public class MyApplication extends Application { private AppComponent mAppComponent; @Override public void onCreate() { super.onCreate(); // 构建Component,传入Application Context mAppComponent = DaggerAppComponent.builder() .contextModule(new ContextModule(this)) .build(); } public AppComponent getAppComponent() { return mAppComponent; } }
5. 在Presenter中获取Interactor
public class MyPresenter { private MyInteractor mInteractor; public MyPresenter() { // 通过Application的Component获取Interactor实例 mInteractor = ((MyApplication) getApplication()).getAppComponent().provideMyInteractor(); // 或者如果Presenter也用构造注入,直接把Interactor作为参数传入更优雅 } }
三、非Activity类获取Context的最优方案
在MVP模式下,我推荐以下优先级:
- Dagger注入Application Context
- 优势:符合依赖注入原则,解耦性强,便于单元测试(可以Mock Context),且不会造成内存泄漏(Application Context生命周期和应用一致)。
- 通过Application类的静态方法获取Context
- 这是退而求其次的方案,比如没有用Dagger的场景。但要注意:必须保存Application Context,不要保存Activity Context,且静态方法要保证线程安全。
- 绝对避免:通过静态变量持有Activity Context,或者从非注入渠道获取Context,极易引发内存泄漏。
最后再提醒几个注意点
- 永远优先用
Application Context,除非你明确需要Activity的生命周期(比如启动Activity、显示Dialog)。 - 检查Dagger生成的代码是否正常(Rebuild Project后看有没有DaggerAppComponent类),如果生成失败,大概率是注解配置有误。
内容的提问来源于stack exchange,提问作者Anubhav
相关产品推荐
相关产品推荐

