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

Android中使用Dagger向非页面类注入单例为空如何解决

问题根因

你手动通过new BackendImp()创建实例时,Dagger不会自动识别类内部的@Inject注解并完成依赖注入,必须主动触发注入流程或者通过构造函数注入依赖。另外你将BackendImp的注入方法定义在了@PerActivity作用域的AbstractActivityComponent中,但BackendImp是全局单例,和Activity生命周期无关联,配置本身也不匹配。

最优解决方案(构造函数注入,符合Dagger最佳实践)

步骤1:修改BackendImp实现构造注入

给BackendImp的构造函数添加@Inject注解,直接通过构造参数传入依赖,无需字段注入:

public class BackendImp implements BackendService {
    private final DataAccessInterface dataAccessInterface;

    @Inject
    public BackendImp(DataAccessInterface dataAccessInterface) {
        this.dataAccessInterface = dataAccessInterface;
    }

    public void save () {
        Car car = unloadCar();
        dataAccessInterface.saveCar(car);
    }
}

步骤2:在ApplicationModule中提供BackendImp单例

新增方法暴露BackendService单例:

@Module
public class ApplicationModule {
    // 原有代码不变

    @Provides
    @Singleton
    BackendService provideBackendService(BackendImp backendImp) {
        return backendImp;
    }
}

步骤3:在ApplicationComponent中添加BackendService暴露方法

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    // 原有方法保留
    Application application();
    Context context();
    DataAccessInterface dataAccessInterface();
    // 新增方法
    BackendService backendService();
}

步骤4:修改Application初始化逻辑,从Dagger组件获取实例

不要手动new实例,直接从ApplicationComponent中获取Dagger已经完成依赖注入的实例:

public class MainApp extends Application {
    public static BackendService backendService;
    private ApplicationComponent appComponent;

    @Override
    public void onCreate () {
        super.onCreate();
        // 初始化ApplicationComponent
        appComponent = ApplicationComponent.Initializer.init(this);
        // 从Dagger组件获取已注入完成的实例
        backendService = appComponent.backendService();
    }
    // 原有其他代码不变
}
备选方案(手动触发字段注入,无需修改原有BackendImp结构)

如果你不想调整BackendImp的现有结构,也可以主动调用Dagger的注入方法完成字段注入:

步骤1:将BackendImp的注入方法迁移到ApplicationComponent

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    // 原有方法保留
    void inject(Application application);
    // 新增BackendImp注入方法
    void inject(BackendImp backendImp);
}

步骤2:手动new实例后触发注入

public class MainApp extends Application {
    public static BackendService backendService;
    private ApplicationComponent appComponent;

    @Override
    public void onCreate () {
        super.onCreate();
        appComponent = ApplicationComponent.Initializer.init(this);
        // 手动创建实例
        backendService = new BackendImp();
        // 主动触发注入,完成dataAccessInterface的赋值
        appComponent.inject((BackendImp) backendService);
    }
    // 原有其他代码不变
}

额外优化建议

你之前在AbstractActivityComponent中定义的void inject (BackendImp inject);可以删除了,BackendImp是全局单例,不需要和Activity作用域的组件绑定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:27:03