I'm trying to inject the viewmodel to the Fragment using hilt, for that I created two modules one for my network component and another for the characters viewmodel.
The network module is installed in SingletonComponent and I need that the characters module installs in the FragmentComponent to get the Viewmodel through "by viewmodels()"
My activity and my fragment are annotated with "@AndroidEntryPoint" and my Application is annotated with "@HiltAndroidApp" my modules are:
@Module
@InstallIn(SingletonComponent::class)
class NetworkModule {
@Singleton
@Provides
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}
@Singleton
@Provides
fun provideAuthorizationInterceptor(): AuthorizationInterceptor =
AuthorizationInterceptor()
@Singleton
@Provides
fun provideInterceptors(
loggingInterceptor: HttpLoggingInterceptor,
authorizationInterceptor: AuthorizationInterceptor
): HttpInterceptors = HttpInterceptors(
listOf(
loggingInterceptor,
authorizationInterceptor
)
)
@Singleton
@Provides
fun provideTimeouts(): HttpTimeouts = HttpTimeouts()
@Singleton
@Provides
fun provideHttpClient(
timeouts: HttpTimeouts,
interceptors: HttpInterceptors
): HttpBuilderFactory = HttpClientBuilderFactory(timeouts, interceptors)
@Singleton
@Provides
fun provideGsonConverter(): GsonFactory = GsonBuilderFactory()
@Singleton
@Provides
fun provideHttpServiceProvider(
httpBuilderFactory: HttpBuilderFactory,
gsonFactory: GsonFactory
): HttpProvider = HttpServiceProvider(httpBuilderFactory, gsonFactory)
}
@Module
@InstallIn(FragmentComponent::class)
class CharacterListModule {
@Singleton
@Provides
fun provideCharacterMapper(): Mapper<CharacterDataContainer, PaginatedCharacters> =
PaginatedCharactersMapper()
@Singleton
@Provides
fun provideCharacterServices(
httpServiceProvider: HttpProvider
): CharacterServices = httpServiceProvider.createService(CharacterServices::class.java)
@Singleton
@Provides
fun provideCharacterListRemoteSource(
characterServices: CharacterServices,
characterMapper: Mapper<CharacterDataContainer, PaginatedCharacters>
): CharacterListSource = CharacterListRemoteSourceImpl(
characterServices,
characterMapper
)
@Singleton
@Provides
fun provideCharacterListRepository(
characterListRemoteSource: CharacterListSource
): CharacterListRepository = CharacterListRepositoryImpl(
characterListRemoteSource
)
@Singleton
@Provides
fun provideCoroutineDispatcher() = Dispatchers.IO
@Singleton
@Provides
fun provideCharacterListUseCase(
coroutineDispatcher: CoroutineDispatcher,
characterListRepository: CharacterListRepository
) = CharacterListUseCase(
coroutineDispatcher,
characterListRepository
)
@Singleton
@Provides
fun provideCharacterUIMapper(): Mapper<Character, CharacterUI> = CharacterUIMapper()
}
and my viewmodel is:
@HiltViewModel
class CharacterListViewModel @Inject constructor(
private val characterListUseCase: CharacterListUseCase,
private val characterUIMapper: Mapper<Character, CharacterUI>
) : ViewModel() {
Also when I use SingletonComponent in both cases the application runs fine, but when try to use FragmentComponent fails:
Finally my dependencies are:
object Hilt {
internal object Versions {
const val hilt = "2.33-beta"
const val hiltViewModel = "1.0.0-alpha01"
}
const val hilt = "com.google.dagger:hilt-android:${Versions.hilt}"
const val hiltCompiler = "com.google.dagger:hilt-android-compiler:${Versions.hilt}"
const val hiltViewModel = "androidx.hilt:hilt-lifecycle-viewmodel:${Versions.hiltViewModel}"
const val hiltViewModelCompiler = "androidx.hilt:hilt-compiler:${Versions.hiltViewModel}"
}
As it names says "FragmentComponent"(s) only live as long as it fragments does. You can't inject something that is fragment scoped into a view model, because viewmodels outlive its fragments lifecycle.. Change "FragmentScoped" with "SingletonScoped".
Please read the official documentation first before working with scopes. 99% of the time, using a "SingletonComponent" is more than enough
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.