Interrompi le app con più moduli

La generazione di codice di Hilt richiede l'accesso a tutti i moduli Gradle che utilizzano Hilt. Il modulo Gradle che compila la tua classe Application deve avere tutti i moduli Hilt e le classi inserite dal costruttore nelle sue dipendenze transitive.

Se il tuo progetto multimodulo è composto da moduli Gradle normali, puoi utilizzare Hilt come descritto in Inserimento delle dipendenze con Hilt. Tuttavia, questo non è il caso delle app che includono moduli delle funzionalità.

Nascondi nei moduli delle funzionalità

Nei moduli delle caratteristiche, il modo in cui i moduli di solito dipendono l'uno dall'altro viene invertito. Di conseguenza, Hilt non può elaborare le annotazioni nei moduli delle funzionalità. Devi utilizzare Dagger per eseguire l'inserimento di dipendenze nei moduli delle funzionalità.

Per risolvere questo problema con i moduli delle funzionalità, devi utilizzare le dipendenze dei componenti. Procedi nel seguente modo:

  1. Dichiara un'interfaccia @EntryPoint nel modulo app (o in qualsiasi altro modulo che può essere elaborato da Hilt) con le dipendenze necessarie per il modulo delle funzionalità.
  2. Crea un componente Dagger che dipenda dall'interfaccia @EntryPoint.
  3. Usa Dagger come di consueto nel modulo delle funzionalità.

Considera l'esempio della pagina Inserimento delle dipendenze con Hilt. Supponi di aggiungere un modulo delle funzionalità login al tuo progetto. Implementi la funzionalità di accesso con un'attività denominata LoginActivity. Ciò significa che puoi ottenere associazioni solo dal componente dell'applicazione.

Per questa funzionalità, è necessario un OkHttpClient con l'associazione authInterceptor.

Innanzitutto, crea un'interfaccia @EntryPoint installata in SingletonComponent con le associazioni necessarie per il modulo 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();
}

Per eseguire l'inserimento dei campi in LoginActivity, crea un componente Dagger che dipenda dall'interfaccia @EntryPoint:

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

Una volta completati questi passaggi, utilizza Dagger come di consueto nel modulo delle funzionalità. Ad esempio, puoi utilizzare le associazioni da SingletonComponent come dipendenza di una classe:

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

Per eseguire l'inserimento dei campi, crea un'istanza del componente Dagger utilizzando applicationContext per ottenere le dipendenze 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);
    ...
  }
}

Per ulteriore contesto sulle dipendenze dei moduli nei moduli delle funzionalità, consulta Dipendenze dei componenti con moduli delle funzionalità.

Per ulteriori informazioni su Dagger su Android, consulta la pagina relativa all'utilizzo di Dagger nelle app per Android.