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

从Dagger2迁移到Hilt:如何迁移带自定义Component.Factory的应用组件

Dagger2 迁移 Hilt:ApplicationComponent.Factory 处理方案

问题背景

将遗留应用从Dagger2迁移到Hilt时,原ApplicationComponent通过Factory绑定多个实例并依赖子组件,转为EntryPoint后无法处理Factory中的额外内容,具体代码如下:

原ApplicationComponent代码

abstract class ApplicationComponent : ApplicationDependencies {

    abstract fun inject(application: MyApp)

    @Component.Factory
    interface Factory {
        fun applicationComponent(
            @BindsInstance myApp: MyApp,
            @BindsInstance sharedPreferences: SharedPreferences,
            @BindsInstance activeActivityProvider: ActiveActivityProvider,
            @BindsInstance appLifecycleObservable: Observable<ApplicationStateEvent>,
            @BindsInstance @EnvironmentName
            environmentName: String,
            schedulersComponent: SchedulerComponent,
            commonComponent: CommonComponent,
        ): ApplicationComponent
    }
}

原MyApp初始化代码

public class MyApp extends Application {
    private ApplicationComponent component;
    // ... 定义 appLifecyleObserver 等逻辑

    public void onCreate() {
        ProcessLifecycleOwner.get().getLifecycle().addObserver(appLifecycleObserver);
        super.onCreate();
        
        // ... 初始化 mSharedPreferences、environmentName 等逻辑

        component = DaggerApplicationComponent.factory().applicationComponent(
                this,
                mSharedPreferences,
                activeActivityProvider,
                appLifecycleRelay,
                environmentName,
                DaggerSchedulersComponent.create(),
                DaggerCommonComponent.factory().commonComponent(this),
        );
        component.inject(this);
    }
}

迁移方案

Hilt没有直接对应Dagger Component.Factory的概念,需将Factory中的参数拆分处理:

  1. 处理@BindsInstance绑定的实例

    • MyApp实例:在MyApp上添加@HiltAndroidApp注解,Hilt自动绑定Application/MyApp类型,无需手动传入。
    • 其余绑定实例(SharedPreferences、ActiveActivityProvider等):创建Hilt单例模块,通过@Provides方法提供实例,复用原初始化逻辑:
      @Module
      @InstallIn(SingletonComponent::class)
      object AppBindingsModule {
          @Provides
          @Singleton
          fun provideSharedPreferences(app: MyApp): SharedPreferences {
              // 复用原代码中初始化mSharedPreferences的逻辑
              return app.getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
          }
      
          @Provides
          @Singleton
          @EnvironmentName
          fun provideEnvironmentName(app: MyApp): String {
              // 复用原代码中获取environmentName的逻辑
              return app.environmentName
          }
      
          @Provides
          @Singleton
          fun provideActiveActivityProvider(): ActiveActivityProvider {
              // 原代码中初始化该实例的逻辑
              return ActiveActivityProviderImpl()
          }
      
          @Provides
          @Singleton
          fun provideAppLifecycleObservable(app: MyApp): Observable<ApplicationStateEvent> {
              // 复用原appLifecycleRelay的逻辑
              return app.appLifecycleRelay
          }
      }
      
  2. 处理依赖的子组件(SchedulerComponent、CommonComponent)

    • 将子组件转为Hilt模块,把原组件提供的依赖移到@InstallIn(SingletonComponent::class)的模块中:
      • 无依赖的SchedulerComponent:直接在模块中提供对应依赖
      • 依赖MyApp的CommonComponent:在@Provides方法中注入MyApp复用逻辑
        示例:
      @Module
      @InstallIn(SingletonComponent::class)
      object CommonModule {
          @Provides
          @Singleton
          fun provideCommonDependency(app: MyApp): CommonDependency {
              // 复用原CommonComponent中提供该依赖的逻辑
              return CommonDependencyImpl(app)
          }
      }
      
  3. 替换原Component注入逻辑

    • 在MyApp上添加@HiltAndroidApp注解,Hilt自动生成SingletonComponent替代原ApplicationComponent
    • 移除原component变量及手动初始化代码,Hilt自动完成注入;若需在MyApp中获取依赖,定义EntryPoint:
      @HiltAndroidApp
      public class MyApp extends Application {
          // ... 保留appLifecyleObserver等逻辑
      
          @Override
          public void onCreate() {
              ProcessLifecycleOwner.get().getLifecycle().addObserver(appLifecycleObserver);
              super.onCreate();
              // 移除原component初始化代码
          }
      
          // 定义EntryPoint用于获取依赖
          @EntryPoint
          @InstallIn(SingletonComponent.class)
          interface AppEntryPoint {
              SharedPreferences getSharedPreferences();
              // 其他需要暴露的依赖
          }
      }
      
  4. 替换原inject方法
    原ApplicationComponent的inject(MyApp)方法无需保留,只需在MyApp中需要注入的字段上添加@Inject注解,Hilt自动完成注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:40:20