該章站在企業(yè)項目角度上如何在MVVM框架上完善并且合理的使用Hilt县耽。
所以如果沒了解MVVM的結構建議可以直接忽略這章句喷。大家知道,MVVM里面View和Model之間有關聯(lián)兔毙,假設一個場景View觸發(fā)一個點擊事件調用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"
}
好了宛乃!添加相關插件自動下載后,我們繼續(xù)蒸辆!
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. 創(chuàng)建一個仿造訪問網絡數據的TestApi 類
class TestApi {
fun getValue(): Int {
return 1
}
}
只是一個簡單的創(chuàng)建返回數據類
5. ViewModel
可以同時看到兩個標記@HiltViewModel
和 @Inject
,那么TestApi在哪里實例化呢酸些?Activity也沒有創(chuàng)建TestApi呀,這就是Hilt方便的地方檐蚜,讓我們看下一個NetworkModule
@HiltViewModel
class ViewModel @Inject constructor(
testApi: TestApi
) : ViewModel() {
val shopBanner = testApi.getValue()
}
6. NetworkModule
通過@Module
魄懂、@InstallIn
、@Provides
闯第、@Singleton
等多個標記市栗,讓Hilt尋找TestApi的構造方法的時候,找到這里,并且調用GetApi方法創(chuàng)建實例填帽。
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun GetApi(): TestApi {
return TestApi()
}
}
7. End
基本就結束了蛛淋,那么大家很奇怪,其實很簡單兩句話代碼放在MainActivity直接實例化不就行了嗎盲赊,其實不是這樣的铣鹏,當項目越龐大的時候,可能改變構造函數的時候哀蘑,那么我們使用Hilt就能很方便的集中在類似NetworkModule
這樣的類處理诚卸,而在Activity這些類中,我們是不需要關心構造函數的绘迁。如果你覺得理解還抽象合溺,那么建議先用平常方式寫Mvvm,最后再用Hilt優(yōu)化這方面缀台,或許會有更深入的理解呢棠赛!
標記符講解表格
標記符 | 標記是為了什么 |
---|---|
@Module | 標記一個module,代表提供一些無法用構造@Inject的依賴, 比如接口, 第三方庫類型, Builder模式構造的對象等 |
@InstallIn | 委托Hilt幫我們管理范圍膛腐,以管理對象的生命周期睛约,通過指定 Hilt 組件告訴 Hilt 綁定在哪些容器中可用,有很多種容器具體可以看圖1 |
@Provides | 提供實例哲身,注釋函數辩涝,以告訴 Hilt 如何提供無法注入構造函數的 類型 |
@ViewModelScoped | 當在ViewModel中引入協(xié)程,如果直接使用CoroutineScope勘天,那么需要在onCleared()方法中取消協(xié)程怔揩,如果忘記取消協(xié)程那么會導致出現內存泄漏等各種問題,此時需要使用ViewModel擴展屬性viewModelScope來實現協(xié)程作用域 |
作用域
只是簡單介紹依賴注入使用方式的實例源碼如下:
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