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

如何在库的基类Application中注入成员?CoreApplication注入Logger遇空指针

解决库模块CoreApplication的成员注入问题

嘿,我来帮你拆解下这个空指针问题的根源,再给你两个靠谱的解决方案:

问题到底出在哪?

你遇到的空指针完全是Application生命周期执行顺序导致的:
当MainApplication启动时,系统会先调用父类CoreApplication的onCreate()方法,这时候你在MainApplication.onCreate()里才会构建Dagger组件并注入,所以CoreApplication里的@Inject Logger logger还没被赋值,直接调用logger.log()肯定会空指针。

而MainApplication和DetailActivity能正常注入,是因为它们的注入操作都在Dagger组件构建完成之后:

  • MainApplication是先构建组件注入自身,再用logger
  • DetailActivity的AndroidInjection.inject(this)是在组件 ready 之后执行的,依赖自然能拿到

解决方案一:延迟CoreApplication的初始化逻辑(推荐,解耦性好)

这个方法不需要修改组件结构,只调整生命周期逻辑:

  1. 先改CoreApplication,把依赖使用的逻辑从onCreate()移到一个新方法里:
public class CoreApplication extends Application {
    @Inject Logger logger;

    @Override
    public void onCreate() {
        super.onCreate();
        // 这里先不碰logger,等注入完成再说
    }

    // 新增这个方法,让子类在注入完成后调用
    protected void afterInject() {
        logger.log();
    }
}
  1. 然后在MainApplication的onCreate()里,完成注入后再触发父类的初始化:
public class MainApplication extends CoreApplication implements HasActivityInjector {
    @Inject Logger logger;
    @Inject DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        // 先构建Dagger组件并注入自身
        DaggerAppComponent.builder().application(this).build().inject(this);
        // 现在父类的logger已经被注入了,放心调用
        afterInject();
        logger.log();
    }

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

解决方案二:让CoreApplication直接获取组件注入自身

如果希望CoreApplication自己搞定注入(不需要子类触发),可以调整组件设计,但要注意模块依赖问题:

  1. 在库模块里定义一个CoreComponent接口:
// 库模块中的CoreComponent
@Singleton
public interface CoreComponent {
    void inject(CoreApplication coreApplication);
}
  1. 让AppComponent继承这个接口:
@Singleton
@Component(modules = { AndroidInjectionModule.class, ApplicationModule.class})
public interface AppComponent extends AndroidInjector<MainApplication>, CoreComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);
        AppComponent build();
    }
}
  1. 修改CoreApplication的onCreate(),直接构建组件并注入自身:
public class CoreApplication extends Application {
    @Inject Logger logger;

    @Override
    public void onCreate() {
        super.onCreate();
        // 构建组件并注入自己
        AppComponent appComponent = DaggerAppComponent.builder().application(this).build();
        appComponent.inject(this);
        logger.log();
    }
}

⚠️ 注意:这种方式会让库模块依赖应用模块的AppComponent,可能造成循环依赖,所以更推荐第一种方案。


最后验证下

别忘了你已经在ApplicationModule里给Logger加了@Singleton,这样不管是CoreApplication、MainApplication还是DetailActivity,拿到的都是同一个实例,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:03:12