5. 【淺入深出理解 dagger、Hilt】 - Hilt進階之MVVM 那麼讓我們直接快速講解 標記符講解表格 作用域

該章站在企業項目角度上如何在MVVM框架上完善並且合理的使用Hilt。

所以如果沒了解MVVM的結構建議可以直接忽略這章。大家知道,MVVM裏面View和Model之間有關聯,假設一個場景View觸發一個點擊事件調用Model查詢,然後Model會調用相關Http類進行查詢,返回數據給Model,Model再返回數據給View。
當然上述表達的不是嚴格意義的MVVM,但是流程相仿,主要是講解如何註解Model和相關Http類,讓他們自動生成

讓我們先看看有哪些類


類名 解釋
MyApplication app的入口
MainActivity 顧名思義就是展示的View
ViewModel MainActivity對應的ViewModel,也是MVVM中的Model
TestApi 一個仿造Http的類,只是單純返回一個數據
NetworkModule 一個製造類,Hilt通過標記自動尋找相關類,然後會找到該類調用相關函數實例化TestApi

那麼讓我們直接快速講解

1. 在Project的build.gradle添加引入
    dependencies {
        ...
        classpath "com.google.dagger:hilt-android-gradle-plugin:2.36"
    }
2. 在module的build.gradle分別兩處地方添加
plugins {
    ...
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}
dependencies {
    ……

    implementation "com.google.dagger:hilt-android:2.37"
    kapt "com.google.dagger:hilt-android-compiler:2.37"
}

好了!添加相關插件自動下載後,我們繼續!

3. HiltAndroidApp標記Application
@HiltAndroidApp
class MyApplication : Application()

跟dagger有點不一樣的是,必須包含一個帶有 @HiltAndroidApp標記的Application類。
當然,別忘記修改AndroidManifest.xml

<application
        android:allowBackup="true"
        android:name=".MyApplication"
        ...
</application>
5. Activity
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val viewModel: ViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.tvName.append(viewModel.shopBanner.toString())
    }
}

大家看到viewModel就很奇怪,沒有標記就能自動生成使用了?其實by viewModels()就已經代表Hilt生成處理了。讓我們往下看

4. 創建一個仿造訪問網絡數據的TestApi 類
class TestApi {
    fun getValue(): Int {
        return 1
    }
}

只是一個簡單的創建返回數據類

5. ViewModel

可以同時看到兩個標記@HiltViewModel@Inject,那麼TestApi在哪裏實例化呢?Activity也沒有創建TestApi呀,這就是Hilt方便的地方,讓我們看下一個NetworkModule

@HiltViewModel
class ViewModel @Inject constructor(
    testApi: TestApi
) : ViewModel() {

    val shopBanner = testApi.getValue()
}
6. NetworkModule

通過@Module@InstallIn@Provides@Singleton等多個標記,讓Hilt尋找TestApi的構造方法的時候,找到這裏,並且調用GetApi方法創建實例。

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Provides
    @Singleton
    fun GetApi(): TestApi {
        return TestApi()
    }

}
7. End

基本就結束了,那麼大家很奇怪,其實很簡單兩句話代碼放在MainActivity直接實例化不就行了嗎,其實不是這樣的,當項目越龐大的時候,可能改變構造函數的時候,那麼我們使用Hilt就能很方便的集中在類似NetworkModule這樣的類處理,而在Activity這些類中,我們是不需要關心構造函數的。如果你覺得理解還抽象,那麼建議先用平常方式寫Mvvm,最後再用Hilt優化這方面,或許會有更深入的理解呢!

標記符講解表格

標記符 標記是爲了什麼
@Module 標記一個module,代表提供一些無法用構造@Inject的依賴, 比如接口, 第三方庫類型, Builder模式構造的對象等
@InstallIn 委託Hilt幫我們管理範圍,以管理對象的生命週期,通過指定 Hilt 組件告訴 Hilt 綁定在哪些容器中可用,有很多種容器具體可以看圖1
@Provides 提供實例,註釋函數,以告訴 Hilt 如何提供無法注入構造函數的 類型
@ViewModelScoped 當在ViewModel中引入協程,如果直接使用CoroutineScope,那麼需要在onCleared()方法中取消協程,如果忘記取消協程那麼會導致出現內存泄漏等各種問題,此時需要使用ViewModel擴展屬性viewModelScope來實現協程作用域

作用域

只是簡單介紹依賴注入使用方式的實例源碼如下:
zhongjhATC/HiltAndDaggerDemo: 演示 Hilt、Dagger 的demo (github.com)

其他相關文章
1. 【淺入深出理解 dagger、Hilt】 - 簡介 - 簡書 (jianshu.com)
2. 【淺入深出理解 dagger、Hilt】 - dagger無參依賴注入 - 簡書 (jianshu.com)
3. 【淺入深出理解 dagger、Hilt】 - dagger有參依賴注入 - 簡書 (jianshu.com)
4. 【淺入深出理解 dagger、Hilt】 - Hilt - 簡書 (jianshu.com)
在 Android 應用中使用 Hilt | Google Developers

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章