Zugriff in Apps mit mehreren Modulen

Die Hilt-Codegenerierung benötigt Zugriff auf alle Gradle-Module, die Hilt verwenden. Das Gradle-Modul, mit dem die Klasse Application kompiliert wird, muss alle Hilt-Module und Konstruktor-Injection-Klassen in seinen Transitiven enthalten.

Wenn Ihr Projekt mit mehreren Modulen aus regulären Gradle-Modulen besteht, können Sie Hilt wie unter Abhängigkeitsinjektion mit Hilt beschrieben verwenden. Dies ist jedoch nicht bei Apps der Fall, die Funktionsmodule enthalten.

Zugriff in Funktionsmodule

Bei Funktionsmodulen wird die Art und Weise, wie Module normalerweise voneinander abhängig sind, umgekehrt. Daher kann Hilt keine Anmerkungen in Featuremodulen verarbeiten. Sie müssen Dagger verwenden, um eine Abhängigkeitsinjektion in Ihren Featuremodulen durchzuführen.

Sie müssen Komponentenabhängigkeiten verwenden, um dieses Problem mit Funktionsmodulen zu lösen. Gehen Sie dazu so vor:

  1. Deklarieren Sie eine @EntryPoint-Schnittstelle im Modul app (oder in einem anderen Modul, das von Hilt verarbeitet werden kann), mit den Abhängigkeiten, die das Funktionsmodul benötigt.
  2. Erstellen Sie eine Dagger-Komponente, die von der @EntryPoint-Schnittstelle abhängt.
  3. Du kannst Dagger wie gewohnt im Funktionsmodul verwenden.

Sehen Sie sich das Beispiel auf der Seite Abhängigkeitsinjektion mit Hit an. Angenommen, Sie fügen Ihrem Projekt ein login-Funktionsmodul hinzu. Sie implementieren die Anmeldefunktion mit einer Aktivität namens LoginActivity. Das bedeutet, dass Sie Bindungen nur von der Anwendungskomponente abrufen können.

Für dieses Feature benötigen Sie einen OkHttpClient mit der Bindung authInterceptor.

Erstellen Sie zuerst eine @EntryPoint-Schnittstelle, die in der SingletonComponent mit den Bindungen installiert ist, die das login-Modul benötigt:

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();
}

Erstellen Sie eine Dagger-Komponente, die von der @EntryPoint-Schnittstelle abhängt, um ein Feld in den LoginActivity einzufügen:

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();
  }
}

Wenn diese Schritte abgeschlossen sind, kannst du Dagger wie gewohnt in deinem Funktionsmodul verwenden. Sie können beispielsweise die Bindungen aus dem SingletonComponent als Abhängigkeit einer Klasse verwenden:

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;
  }
  ...
}

Um eine Feldeinschleusung durchzuführen, erstellen Sie mit applicationContext eine Instanz der Dagger-Komponente, um die SingletonComponent-Abhängigkeiten abzurufen:

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);
    ...
  }
}

Weitere Informationen zu Modulabhängigkeiten in Feature-Modulen finden Sie unter Komponentenabhängigkeiten mit Feature-Modulen.

Weitere Informationen zu Dagger auf Android finden Sie unter Dolgger in Android-Apps verwenden.