多模組應用程式中的 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 模組所需的繫結:

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

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

 
@AuthInterceptorOkHttpClient
 
fun okHttpClient(): OkHttpClient
}
// LoginModuleDependencies.java - File in the app module.

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

 
@AuthInterceptorOkHttpClient
 
OkHttpClient okHttpClient();
}

若要在 LoginActivity 中執行欄位插入作業,請建立依附於 @EntryPoint 介面的 Dagger 元件:

KotlinJava
// 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
 
}
}
// 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 的繫結做為類別的依附元件:

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

class LoginAnalyticsAdapter @Inject constructor(
 
@AuthInterceptorOkHttpClient okHttpClient: OkHttpClient
) { ... }
// 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 依附元件:

KotlinJava
// 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)
   
...
 
}
}
// 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」。