Ric*_*ard 1 android dependency-injection dagger-2 retrofit2 dagger-hilt
我刚刚学习了手动依赖注入,但我正在尝试使用 Hilt 来处理这些依赖注入。
我想将 a 注入ViewModel到Fragment. 该片段包含在Activity. 现在,我已经添加了注解Application,Activity和Fragment。
@HiltAndroidApp
class MovieCatalogueApplication : Application()
Run Code Online (Sandbox Code Playgroud)
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
...
}
Run Code Online (Sandbox Code Playgroud)
@AndroidEntryPoint
class HomeFragment : Fragment() {
private lateinit var binding: FragHomeBinding
private val viewmodel: HomeViewModel by viewModels()
...
Run Code Online (Sandbox Code Playgroud)
可以看出,我的HomeFragment依赖于HomeViewModel. 我已经添加了一个ViewModel 注入,如此处所述。
class HomeViewModel @ViewModelInject constructor(
private val movieRepository: MovieRepository,
private val showRepository: ShowRepository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
...
}
Run Code Online (Sandbox Code Playgroud)
但是,ViewModel需要两个存储库。现在,我的MovieRepository就是这样。
class MovieRepository (private val movieApi: MovieService) {
...
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,MovieService会使用 Retrofit 创建的Retrofit.create(class)方法。用来创建的界面MovieService是这样的。
interface MovieService {
...
}
Run Code Online (Sandbox Code Playgroud)
为了获得我的 Retrofit 实例,我使用了以下代码。
object RetrofitService {
...
private var _retrofit: Retrofit? = null
val retrofit: Retrofit
get() {
return when (_retrofit) {
null -> {
_retrofit = Retrofit.Builder()
.client(client)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
_retrofit!!
}
else -> _retrofit!!
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不太确定如何将 Retrofit 注入 Repository 以供我ViewModel以后使用。有人可以给我一些有关如何执行此操作的指示或分步说明吗?
显然,这并不像看起来那么难。
您必须首先定义Hilt的绑定信息。绑定信息告诉 Hilt 如何提供指定的依赖项的实例。因为MovieService是使用构建器模式使用 Retrofit(不是您自己创建的第 3 方类)创建的,所以不能使用构造函数注入,而必须使用Hilt 模块和注解@Provides来告诉 Hilt 此绑定信息.
如文档中所述,您创建的 Hilt 模块中的注释函数将向 Hilt 提供以下信息,以便 Hilt 可以提供依赖项的实例。
• 函数返回类型告诉 Hilt 函数提供什么类型的实例。
• 函数参数告诉 Hilt 相应类型的依赖关系。
• 函数体告诉 Hilt 如何提供相应类型的实例。每次需要提供该类型的实例时,Hilt 都会执行函数体。
最后只需要修改MovieRepository类,为每个存储库添加一个模块,并在告诉 Hilt 如何提供 Retrofit 创建的服务实例的函数中添加注解@Provides。
代码。
class MovieRepository @Inject constructor(
private val movieApi: MovieService
) {
...
}
Run Code Online (Sandbox Code Playgroud)
interface MovieService {
...
}
@Module
@InstallIn(ActivityRetainedComponent::class)
object MovieModule {
@Provides
fun provideMovieService(): MovieService
= RetrofitService.retrofit.create(MovieService::class.java)
}
Run Code Online (Sandbox Code Playgroud)
如您所见,注解中ActivityRetainedComponent引用了 ,@InstallIn因为 Repository 将被注入到ViewModel. 每个 Android 组件都与不同的 Hilt 组件相关联。