Android Jetpack架構(gòu)組件(八)— Hilt

一、Hilt簡介

Hilt Google開源的一個 Android 的依賴注入庫,其實(shí)是基于 Dagger。
Hilt 是專門為android打造的 ,可以使我們的代碼 盡量的簡化
Hilt 創(chuàng)建了一組標(biāo)準(zhǔn)的 組件和作用域。這些組件會自動集成到 Android 程序中的生命周期中。在使用的時候可以指定使用的范圍,事件作用在對應(yīng)的生命周期當(dāng)中。

1、依賴注入

Dependency Injection,簡稱DI;
作用:使代碼解耦,便于復(fù)用,重構(gòu)和測試

類通常需要引用其他類,可通過以下三種方式獲取所需的對象:

  1. 在類中創(chuàng)建所需依賴項的實(shí)例
  2. 通過父類或其他類獲取
  3. 以參數(shù)形式提供,可以在構(gòu)造類時提供這些依賴項,或者將這些依賴項傳入需要各個依賴項的函數(shù)

第三種方式就是依賴項注入

2、Android中的依賴注入方式

1.手動依賴注入
(1)、構(gòu)造函數(shù)注入
//在構(gòu)造類時提供這些依賴項
class Car (private val driver: Driver) {
    fun run() {
        driver.run()
    }
}
val driver = Driver()
val car= Car(driver)
car.run()
(2)、字段注入(或 setter 注入)
//將依賴項傳入需要依賴項的函數(shù)
class Car {
    lateinit var driver: Driver
    fun run() = driver.run()
}
val car = Car()
val driver = Driver()
car.driver = driver
car.use()

上面兩種都是手動依賴項注入,但是如果依賴項和類過多,手動依賴注入就會產(chǎn)生一些問題:

1. 使用越來越繁瑣;
2. 產(chǎn)生大量模板代碼;
3. 必須按順序聲明依賴項;
4. 很難重復(fù)使用對象;
2.自動依賴注入框架

有一些庫通過自動執(zhí)行創(chuàng)建和提供依賴項的過程解決此問題,實(shí)現(xiàn)原理有如下幾種方案:

1. 通過反射,在運(yùn)行時連接依賴項;
2. 通過注解,編譯時生成連接依賴項的代碼;
3. kotlin 強(qiáng)大的語法糖和函數(shù)式編程;
(1)、Dagger

Android領(lǐng)域最廣為熟知的依賴注入框架

  • Dagger 1.x版本:
    Square基于反射實(shí)現(xiàn)的,有兩個缺點(diǎn)一個是反射的耗時,另一個是反射是運(yùn)行時的,編譯期不會報錯。而使用難度較高,剛接觸時有經(jīng)常容易寫錯,造成開發(fā)效率底;
  • Dagger 2.x版本:
    Google基于Java注解實(shí)現(xiàn)的,完美解決了上述問題,
(2)、Koin

為 Kotlin 開發(fā)者提供的一個實(shí)用型輕量級依賴注入框架,采用純 Kotlin 語言編寫而成,僅使用功能解析,無代理、無代碼生成、無反射(通過kotlin 強(qiáng)大的語法糖(例如 Inline、Reified 等等)和函數(shù)式編程實(shí)現(xiàn));

(3)、Hilt

由于Dagger的復(fù)雜度和使用難度較大,Android團(tuán)隊聯(lián)合Dagger2團(tuán)隊,一起開發(fā)出來的一個專門面向Android的依賴注入框架Hilt,最明顯的特征就是:1. 簡單;2. 提供了Android專屬的API;3. Google官方支持,和Jetpack其他組件配合使用;

Hilt 通過為項目中的每個 Android 類提供容器并自動為您管理其生命周期,定義了一種在應(yīng)用中執(zhí)行 DI 的標(biāo)準(zhǔn)方法。
Hilt 在熱門 DI 庫 Dagger 的基礎(chǔ)上構(gòu)建而成,因而能夠受益于 Dagger 提供的編譯時正確性、運(yùn)行時性能、可伸縮性和 Android Studio 支持。

二、Hilt的使用

1、依賴版本配置

項目根build.gradle依賴

ext.kotlin_version = "1.5.0"http://kotlin版本
ext.hilt_version = '2.35'//hilt版本
repositories {
    google()
    mavenCentral()
}
dependencies {
    classpath "com.android.tools.build:gradle:4.2.1"
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath 'com.google.dagger:hilt-android-gradle-plugin:2.35'
}

項目app中build.gradle依賴

implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"

項目模塊中build.gradle所使用插件

id 'kotlin-kapt'
id 'kotlin-android-extensions'

2、Hilt應(yīng)用

1.定義Hilt應(yīng)用類
  • 用@HiltAndroidApp注解Application;所有使用Hilt注入框架的應(yīng)用都必須包含一個帶有 @HiltAndroidApp 注釋的 Application 類。
  • @HiltAndroidApp注解 會觸發(fā) Hilt 的代碼生成操作,生成的代碼包括應(yīng)用的一個基類,該基類充當(dāng)應(yīng)用級依賴項容器;
@HiltAndroidApp
class MyApplication : MultiDexApplication() {

}

然后,在AndroidManifest.xml中引入我們自定義的Application類。此時,生成的Hilt組件會附加到 Application 對象的生命周期,并為其提供依賴項。此外,由于它也是應(yīng)用的父組件,所以其他組件可以訪問它提供的依賴項。

2.創(chuàng)建注入類

為了執(zhí)行字段注入,需要在類的構(gòu)造函數(shù)中使用 @Inject 注解,以告知 Hilt 如何提供該類的實(shí)例

class Car @Inject constructor() {
    var name: String = ""

    fun run() {
    }
}

使用 @Inject 注釋執(zhí)行字段
@AndroidEntryPoint 會為項目中的每個 Android 類生成一個單獨(dú)的 Hilt 組件。這些組件可以從它們各自的父類接收依賴項, 如需從組件獲取依賴項,請使用 @Inject 注釋執(zhí)行字段注入, 注意:Hilt注入的字段是不可以聲明成private的;

3.依賴項注入 Android 類

用@AndroidEntryPoint注釋類
目前支持6類入口點(diǎn):Application(通過使用 @HiltAndroidApp),Activity,F(xiàn)ragment,View,Service,BroadcastReceiver

使用 @AndroidEntryPoint 注解 Android 類,還必須為依賴于該類的 Android 類添加注釋,例如為注解 fragment ,則還必須為該 fragment 依賴的 Activity 添加@AndroidEntryPoint注釋。

@AndroidEntryPoint
class HiltActivity : AppCompatActivity() {
    @Inject
    lateinit var car: Car
}

注意:帶參數(shù)的依賴注入,需要構(gòu)造函數(shù)中所依賴的所有其他對象都支持依賴注入;例如:Car的構(gòu)造函數(shù)有Engine,則Engine構(gòu)造函數(shù)也需要@Inject。

3、Hilt模塊

有時一些類型參數(shù)(如接口或來自外部庫的類)不能通過構(gòu)造函數(shù)注入,對于這種情況,我們可以使用Hilt 模塊來向Hilt提供綁定信息。

Hilt模塊是一個帶有@Module注釋的類,并使用 @InstallIn 設(shè)置作用域。與Dagger模塊的作用一樣,它會告知Hilt如何提供某些類型的實(shí)例。與Dagger模塊不同的是,我們必須使用@InstallIn注解為Hilt模塊添加注釋,以告知Hilt模塊將用在哪個Android類中。

1.@Binds注入接口

由于Phone是一個接口,無法通過構(gòu)造函數(shù)注入Hilt,而應(yīng)向Hilt提供綁定信息。即在Hilt模塊內(nèi)創(chuàng)建一個帶有@Binds注釋的抽象函數(shù)。

通常,帶有注釋的函數(shù)會向Hilt提供以下信息:

  1. 函數(shù)返回類型會告知Hilt函數(shù)提供的是哪個接口的實(shí)例。
  2. 函數(shù)參數(shù)會告知Hilt需要提供哪種實(shí)現(xiàn)。
//1. 接口
interface Phone {
    fun call()
}
//2. 實(shí)現(xiàn)類
class Huawei @Inject constructor() : Phone {
    override fun call() {
    }
}
//3. 被注入的類,入?yún)⑹墙涌陬愋?class People @Inject constructor(val phone: Phone) {
    fun call() {
        phone.call()
    }
}
//4. 使用@Binds注入接口實(shí)例
@Module
@InstallIn(ActivityComponent::class)
abstract class PhoneModel {
    @Binds
    abstract fun bindPhone(phone: Huawei): Phone
}
//5. 使用注入的實(shí)例
@AndroidEntryPoint
class HiltActivity : AppCompatActivity() {
    @Inject
    lateinit var people: People

    fun test() {
        people.phone.call()
    }
}

由于PhoneModel 帶有 @InstallIn(ActivityComponent.class) 注釋,因?yàn)槲覀兛梢詫⒃撘蕾図椬⑷階ctivity中。并且,PhoneModel中的所有依賴項都可以在所有Activity中使用。

2.@Provides注入實(shí)例

如果某個類不歸您所有(因?yàn)樗鼇碜酝獠繋?,?Retrofit、OkHttpClient 或 Room 數(shù)據(jù)庫等類),或者必須使用構(gòu)建器模式創(chuàng)建實(shí)例,也無法通過構(gòu)造函數(shù)注入。

這種情況注入方法是在Hilt模塊內(nèi)創(chuàng)建一個函數(shù),然后使用@Provides為該函數(shù)添加注釋。

帶有注釋的函數(shù)會向 Hilt 提供以下信息:

  1. 函數(shù)返回類型會告知 Hilt 函數(shù)提供哪個類型的實(shí)例。
  2. 函數(shù)參數(shù)會告知 Hilt 相應(yīng)類型的依賴項。
  3. 函數(shù)主體會告知 Hilt 如何提供相應(yīng)類型的實(shí)例。每當(dāng)需要提供該類型的實(shí)例時,Hilt 都會執(zhí)行函數(shù)主體。
@Module
@InstallIn(SingletonComponent::class)
class DINetworkModule {

    /**
     * [OkHttpClient]依賴提供方法
     *
     * @return OkHttpClient
     */
    @Singleton
    @Provides
    fun provideOkHttpClient(): OkHttpClient {
        // 日志攔截器部分
        val level = if (BuildConfig.VERSION_TYPE != VersionStatus.RELEASE) BODY else NONE
        val logInterceptor = HttpLoggingInterceptor().setLevel(level)

        return OkHttpClient.Builder()
            .retryOnConnectionFailure(true)
            .connectTimeout(15L * 1000L, TimeUnit.MILLISECONDS)
            .readTimeout(20L * 1000L, TimeUnit.MILLISECONDS)
            .writeTimeout(20L * 1000L, TimeUnit.MILLISECONDS)
            .addInterceptor(logInterceptor)
//            .addInterceptor(CookiesInterceptor())
            .build()
    }

    /**
     * 項目主要服務(wù)器地址的[Retrofit]依賴提供方法
     *
     * @param okHttpClient OkHttpClient OkHttp客戶端
     * @return Retrofit
     */
    @Singleton
    @Provides
    fun provideMainRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl(HttpBaseUrlConstant.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()
    }
}
3.限定符
  • 限定符也是一種注解,當(dāng)為某個類型定義了多個綁定時,我們可以使用它來標(biāo)識該類型的特定綁定。
  • 使用@Qualifier注解實(shí)現(xiàn)限定符。
3.1為同一類型提供多個綁定

如果需要讓Hilt以依賴項的形式提供同一類型的不同實(shí)現(xiàn),那么必須向 Hilt 提供多個綁定,同一類型定義多個綁定可以使用限定符來實(shí)現(xiàn)。

//1. 接口和實(shí)現(xiàn)類
interface Phone {
    fun call()
}

class Huawei @Inject constructor() : Phone {
    override fun call() {
    }
}

class Xiaomi @Inject constructor() : Phone {
    override fun call() {
    }
}

//2. 創(chuàng)建多個類型的注解
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class BindHuawei

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class BindXiaomi

//@Retention:注解的生命周期
//AnnotationRetention.SOURCE:僅編譯期,不存儲在二進(jìn)制輸出中
//AnnotationRetention.BINARY:存儲在二進(jìn)制輸出中,但對反射不可見
//AnnotationRetention.RUNTIME:存儲在二進(jìn)制輸出中,對反射可見


//3. 在Hilt模塊中使用注解
@Module
@InstallIn(ActivityComponent::class)
abstract class PhoneModel {
    @BindHuawei
    @Binds
    abstract fun bindHuawei(cpu: Huawei): Phone

    @ BindXiaomi
    @Binds
    abstract fun bindXiaomi(cpu: Xiaomi): Phone
}

//4. 使用依賴注入獲取實(shí)例,可以用在字段注解,也可以用在構(gòu)造函數(shù)或者方法入?yún)⒅?@AndroidEntryPoint
class HiltActivity : AppCompatActivity() {
    @BindHuawei
    @Inject
    lateinit var huawei: Phone

    @BindXiaomi
    @Inject
    lateinit var xiaomi: Phone

    fun use() {
        huawei.call()
        xiaomi.call()
    }
}

如果需要向某個類型添加限定符,那么應(yīng)該向提供該依賴項的所有可能的渠道都添加限定符。這是因?yàn)樽尰镜膶?shí)現(xiàn)或通用的實(shí)現(xiàn)在不帶限定符的情況下避免出錯,也是為了避免導(dǎo)致Hilt注入錯誤的依賴項。

3.2Hilt中的預(yù)定義限定符

Hilt提供了一些預(yù)定義的限定符。
Hilt 提供的@ApplicationContext 和 @ActivityContext 限定符用來獲取Context 類

class ModuleOne @Inject constructor(@ApplicationContext private val context: Context)

class ModuleTwo @Inject constructor(@ActivityContext private val context: Context)

對于Application和Activity這兩個類型,Hilt也是給它們預(yù)置好了注入功能(必須是這兩個,即使子類也不可以)

class ModuleOne @Inject constructor(val application: Application)

class ModuleTwo @Inject constructor(val activity: Activity)

4、Hilt內(nèi)置組件類型

@Module:將這個類注冊為module
@InstallIn():把這個模塊安裝到哪個組件中

Hilt內(nèi)置了7種組件可選:
  1. SingletonComponent(ApplicationComponent廢棄):
    對應(yīng)Application,依賴注入實(shí)例可以在全項目中使用
  2. ActivityRetainedComponent:
    對應(yīng)ViewModel(在配置更改后仍然存在,因此它在第一次調(diào)用 Activity#onCreate() 時創(chuàng)建,在最后一次調(diào)用 Activity#onDestroy() 時銷毀)
  3. ActivityComponent:
    對應(yīng)Activity,Activity中包含的Fragment和View也可以使用;
  4. FragmentComponent:
    對應(yīng)Fragment
  5. ViewComponent:
    對應(yīng)View
  6. ViewWithFragmentComponent:
    對應(yīng)帶有 @WithFragmentBindings 注釋的 View
  7. ServiceComponent:
    對應(yīng)Service
Hilt內(nèi)置7種組件作用域注解:
  1. @Singleton:
    對應(yīng)組件ApplicationComponent,整個項目共享同一個實(shí)例
  2. @ActivityRetainedScope:
    對應(yīng)組件ActivityRetainedComponent
  3. @ActivityScoped:
    對應(yīng)組件ActivityComponent,在同一個Activity(包括其包含的Fragment和View中)內(nèi)部將會共享同一個實(shí)例
  4. @FragmentScoped:
    對應(yīng)組件FragmentComponent
  5. @ViewScoped:
    對應(yīng)組件ViewComponent和ViewWithFragmentComponent;
  6. @ServiceScopedService:
    對應(yīng)ServiceComponent
組件的層次結(jié)構(gòu)。

將Hilt模塊安裝到組件后,其綁定就可以與其他綁定的依賴項相互發(fā)生作用了,也可以用作組件層次結(jié)構(gòu)中該組件下的任何子組件中其他綁定的依賴項。


組件的層次結(jié)構(gòu)
組件

注意:ApplicationComponent廢棄,改為SingletonComponent

5、ViewModel的依賴注入

ViewModel中創(chuàng)建Repository并在Activity中使用

//1. 倉庫層
class Repository @Inject constructor(){
    @Inject
    lateinit var apiService: ApiService
    suspend fun requestInfo(): RepoResponse {
        return apiService.requestInfo()
    }
}
//2. ViewModel層
@ActivityRetainedScoped
class MyViewModel @Inject constructor(private val repository: Repository): ViewModel() {
    var ld_result: MutableLiveData<String> = MutableLiveData()
    fun requestInfo() {
        viewModelScope.launch {
            runCatching {
                withContext(Dispatchers.IO){
                    repository. requestInfo()
                }
            }.onSuccess {
                ld_result.value=gson().toJson(it).toString()
            }.onFailure {
                ld_result.value=it.message
            }
        }
    }
}
//3. Activity層
@AndroidEntryPoint
class HiltActivity : AppCompatActivity() {

    @Inject
    lateinit var viewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_hilt)
        viewModel.ld_result.observe(this, Observer {

        })
        viewModel. requestInfo()
    }
}
@HiltViewModel注解ViewModel

Hilt專門為其提供了一種獨(dú)立的依賴注入方式: @HiltViewModel來獲取ViewModel實(shí)例。

//1. 倉庫層
class CommonRepository @Inject constructor() : BaseRepository() {

    @Inject
    lateinit var mApi: HomeApiService

    suspend fun requestHome(
        callback: RequestCallback<HomeBean>
    ) = request(callback) { mApi.requestHome() }

}

//2. ViewModel層
@HiltViewModel
class HomeViewModel @Inject constructor(private val mRepository: CommonRepository) :
    BaseViewModel() {

}

//3. Activity層
@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainLayoutBinding, HomeViewModel>() {

    val mViewModel: HomeViewModel by viewModels()
//  或  val mViewModel: HomeViewModel by lazy { ViewModelProvider(this).get(HomeViewModel::class.java) }
 
}
SavedStateHandle 和 @assist注解

Activity/Fragment被銷毀一般有三種情況:

  1. 界面關(guān)閉或退出應(yīng)用
  2. Activity 配置 (configuration) 被改變,如旋轉(zhuǎn)屏幕時;
  3. 在后臺時因運(yùn)行內(nèi)存不足被系統(tǒng)回收;

ViewModel 會處理2的情況,而3的情況就需要使用onSaveInstanceState()保存數(shù)據(jù),重建時用SavedStateHandle恢復(fù)數(shù)據(jù),就要用@assist 注解添加 SavedStateHandle 依賴項

@HiltViewModel
class HomeViewModel @Inject constructor(private val mRepository: CommonRepository,
    //SavedStateHandle 用于進(jìn)程被終止時,保存和恢復(fù)數(shù)據(jù)
    @Assisted private val savedStateHandle: SavedStateHandle
) ) : BaseViewModel() {
    var ld_result: MutableLiveData<String> = MutableLiveData()
    private val userId: MutableLiveData<String> = savedStateHandle.getLiveData("userId")

    
}

6、Hilt不支持的注入依賴項

Hilt支持一些最常見的 Android 類,如Application、Activity、Fragment、View、Service和BroadcastReceiver。如果要在Hilt不支持的類中執(zhí)行字段注入:

  • 可以使用 @EntryPoint 注釋創(chuàng)建入口點(diǎn), 調(diào)用EntryPointAccessors的靜態(tài)方法來獲得自定義入口點(diǎn)的實(shí)例,入口點(diǎn)是由Hilt管理的代碼與并非由Hilt管理的代碼之間的邊界,它是代碼首次進(jìn)入Hilt所管理對象的圖的位置,入口點(diǎn)允許Hilt使用它并不管理的代碼提供依賴關(guān)系圖中的依賴項。
  • EntryPointAccessors提供了四個靜態(tài)方法:fromActivity、fromApplication、fromFragment、fromView,根據(jù)自定義入口的MyEntryPoint的注解@InstallIn所指定的范圍選擇對應(yīng)的獲取方法;
//1、注冊創(chuàng)建入口點(diǎn)
@EntryPoint
@InstallIn(ApplicationComponent::class)
interface MyEntryPoint{
    fun getRetrofit():Retrofit
}
//2、使用EntryPointAccessors獲取實(shí)例
Context appContext = getContext().getApplicationContext();
MyEntryPoint hiltEntryPoint =EntryPointAccessors.fromApplication(appContext, MyEntryPoint.class);
Retrofit retrofit = hiltEntryPoint. getRetrofit();

參數(shù)是組件實(shí)例或充當(dāng)組件持有者的 @AndroidEntryPoint 對象,使用時以參數(shù)形式傳遞的組件和 EntryPointAccessors 靜態(tài)方法都與 @EntryPoint 接口上的 @InstallIn 注釋中的 Android 類匹配。

在本例中,我們使用 ApplicationContext 作為檢索入口點(diǎn),因?yàn)槿肟邳c(diǎn)安裝在 ApplicationComponent 中。如果需要檢索的綁定位于 ActivityComponent 中那么改為 ActivityContext即可。

7、Hilt注入ContentProvider

  • Hilt支持的入口點(diǎn)中少了一個關(guān)鍵的Android組件:ContentProvider, 主要原因就是ContentProvider.onCreate() 在Application的onCreate() 之前執(zhí)行,因此很多人會利用這個特性去進(jìn)行提前初始化, 詳見Android Jetpack系列--5. App Startup使用詳解, 而Hilt的工作原理是從Application.onCreate()中開始的,即ContentProvider.onCreate()執(zhí)行之前,Hilt的所有功能都還無法正常工作;
class MyContentProvider : ContentProvider() {
    override fun onCreate(): Boolean {
        context?.let {
            val appContext=it.applicationContext
            //調(diào)用EntryPointAccessors.fromApplication()函數(shù)來獲得自定義入口點(diǎn)的實(shí)例
            val entryPoint=EntryPointAccessors.fromApplication(appContext,MyEntryPoint::class.java)
            //再調(diào)用入口點(diǎn)中定義的getRetrofit()函數(shù)就能得到Retrofit的實(shí)例
            val retrofit=entryPoint.getRetrofit()
        }
        return true
    }
}

8、Hilt注入Startup

App Startup 會默認(rèn)提供一個 InitializationProvider,InitializationProvider 繼承 ContentProvider;

class LjyInitializer : Initializer<Unit> {
    override fun create(context: Context) {
        //調(diào)用EntryPointAccessors.fromApplication()函數(shù)來獲得自定義入口點(diǎn)的實(shí)例
        val entryPoint= EntryPointAccessors.fromApplication(context, MyEntryPoint::class.java)
        //再調(diào)用入口點(diǎn)中定義的getRetrofit()函數(shù)就能得到Retrofit的實(shí)例
        val retrofit=entryPoint.getRetrofit()
        LjyLogUtil.d("retrofit:$retrofit")
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        return emptyList()
    }
}

報錯解決:

Expected @HiltAndroidApp to have a value. Did you forget to apply the Gradle Plugin?

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation":
                             "$projectDir/schemas".toString()]
            }
        }
    }
}

9、Hilt注入WorkManager

使用Hilt注入WorkManager,需要在Gradle文件中添加如下一些額外的依賴項

dependencies {
  implementation 'androidx.hilt:hilt-work:1.0.0-alpha01'
  // Kotlin.
  kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
  // Java.
  annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}

首先,在Worker對象的構(gòu)造函數(shù)中使用@WorkerInject注解來注入一個 Worker,然后在 Worker對象中使用@Singleton或未限定作用域的綁定對象的作用域,還必須使用 @Assisted 為 Context 和 WorkerParameters 依賴項添加注釋。

public class ExampleWorker extends Worker {

  private final WorkerDependency workerDependency;

  @WorkerInject
  ExampleWorker(
    @Assisted @NonNull Context context,
    @Assisted @NonNull WorkerParameters params,
    WorkerDependency workerDependency
  ) {
    super(context, params);
    this.workerDependency = workerDependency;
  }
  ...
}

然后,讓Application類實(shí)現(xiàn)Configuration.Provider接口,注入HiltWorkFactory 的實(shí)例,并將其傳入WorkManager配置,如下所示。

@HiltAndroidApp
public class ExampleApplication extends Application implements Configuration.Provider {

  @Inject HiltWorkerFactory workerFactory;

  @Override
  public Configuration getWorkManagerConfiguration() {
    return Configuration.Builder()
             .setWorkerFactory(workerFactory)
             .build();
  }
}

參考:
Android Jetpack--Hilt使用詳解
Android Jetpack架構(gòu)組件(十二)之Hilt

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容