多模块应用中的 Hilt

Hilt 代码生成需要访问所有使用 Hilt 的 Gradle 模块。编译您的 Application 类的 Gradle 模块需要在其传递依赖项中包含所有 Hilt 模块和构造函数注入的类。

如果您的多模块项目由常规 Gradle 模块组成,那么您可以按照 使用 Hilt 进行依赖项注入 中的说明使用 Hilt。但是,包含 功能模块 的应用并非如此。

功能模块中的 Hilt

在功能模块中,模块之间的依赖关系通常是反转的。因此,Hilt 无法处理功能模块中的注释。您必须使用 Dagger 在您的功能模块中执行依赖项注入。

您必须使用组件依赖关系来解决功能模块的这个问题。请按照以下步骤操作

  1. app 模块(或在任何其他可以由 Hilt 处理的模块中)声明一个 @EntryPoint 接口,该接口包含功能模块所需的依赖关系。
  2. 创建一个依赖于 @EntryPoint 接口的 Dagger 组件。
  3. 在功能模块中按平常使用 Dagger。

请参考 使用 Hilt 进行依赖项注入 页面中的示例。假设您向项目添加了一个 login 功能模块。您使用一个名为 LoginActivity 的活动来实现登录功能。这意味着您只能从应用程序组件获取绑定。

对于此功能,您需要一个具有 authInterceptor 绑定的 OkHttpClient

首先,创建一个安装在 SingletonComponent 中的 @EntryPoint 接口,其中包含 login 模块所需的绑定

Kotlin

// LoginModuleDependencies.kt - File in the app module.

@EntryPoint
@InstallIn(SingletonComponent::class)
interface LoginModuleDependencies {

  @AuthInterceptorOkHttpClient
  fun okHttpClient(): OkHttpClient
}

Java

// LoginModuleDependencies.java - File in the app module.

@EntryPoint
@InstallIn(SingletonComponent.class)
public interface LoginModuleDependencies {

  @AuthInterceptorOkHttpClient
  OkHttpClient okHttpClient();
}

要在 LoginActivity 中执行字段注入,请创建一个依赖于 @EntryPoint 接口的 Dagger 组件

Kotlin

// LoginComponent.kt - File in the login module.

@Component(dependencies = [LoginModuleDependencies::class])
interface LoginComponent {

  fun inject(activity: LoginActivity)

  @Component.Builder
  interface Builder {
    fun context(@BindsInstance context: Context): Builder
    fun appDependencies(loginModuleDependencies: LoginModuleDependencies): Builder
    fun build(): LoginComponent
  }
}

Java

// LoginComponent.java - File in the login module.

@Component(dependencies = LoginModuleDependencies.class)
public interface LoginComponent {

  void inject(LoginActivity loginActivity);

  @Component.Builder
  interface Builder {
    Builder context(@BindsInstance Context context);
    Builder appDependencies(LoginModuleDependencies loginModuleDependencies);
    LoginComponent build();
  }
}

完成这些步骤后,在您的功能模块中按平常使用 Dagger。例如,您可以将来自 SingletonComponent 的绑定用作类的依赖项

Kotlin

// LoginAnalyticsAdapter.kt - File in the login module.

class LoginAnalyticsAdapter @Inject constructor(
  @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
) { ... }

Java

// LoginAnalyticsAdapter.java - File in the login module.

public class LoginAnalyticsAdapter {

  private final OkHttpClient okHttpClient;

  @Inject
  LoginAnalyticsAdapter(
    @AuthInterceptorOkHttpClient OkHttpClient okHttpClient
  ) {
    this.okHttpClient = okHttpClient;
  }
  ...
}

要执行字段注入,使用 applicationContext 创建 Dagger 组件的实例,以获取 SingletonComponent 依赖项。

Kotlin

// LoginActivity.kt - File in the login module.

class LoginActivity : AppCompatActivity() {

  @Inject
  lateinit var loginAnalyticsAdapter: LoginAnalyticsAdapter

  override fun onCreate(savedInstanceState: Bundle?) {
    DaggerLoginComponent.builder()
        .context(this)
        .appDependencies(
          EntryPointAccessors.fromApplication(
            applicationContext,
            LoginModuleDependencies::class.java
          )
        )
        .build()
        .inject(this)

    super.onCreate(savedInstanceState)
    ...
  }
}

Java

// LoginActivity.java - File in the login module.

public class LoginActivity extends AppCompatActivity {

  @Inject
  LoginAnalyticsAdapter loginAnalyticsAdapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    DaggerLoginComponent.builder()
        .context(this)
        .appDependencies(
          EntryPointAccessors.fromApplication(
            getApplicationContext(),
            LoginModuleDependencies.class
          )
        )
        .build()
        .inject(this);

    super.onCreate(savedInstanceState);
    ...
  }
}

有关功能模块中模块依赖项的更多上下文,请参阅 带有功能模块的组件依赖项

有关 Android 上 Dagger 的更多信息,请参阅 在 Android 应用中使用 Dagger