In my fragments I would like to remove such lines:
val retrofitService = RetrofitService.getInstance(requireContext())
val mainRepository = MainRepository(retrofitService)
viewModel = ViewModelProvider(
this@FrgName,
AppVMFactory(mainRepository)
)[AppViewModel::class.java]
I have such view model:
class AppViewModel @Inject constructor(private val mainRepository: MainRepository) : ViewModel() {...}
such factory:
class AppVMFactory @Inject constructor(private val repository: MainRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return if (modelClass.isAssignableFrom(AppViewModel::class.java)) {
AppViewModel(this.repository) as T
} else {
throw IllegalArgumentException("ViewModel Not Found")
}
}
}
such repository:
class MainRepository @Inject constructor(val retrofitService: RetrofitService) {
suspend fun logIn(loginObject: JsonObject) = retrofitService.auth(loginObject)
....
}
and service contains all requests. As we know we can use in fragments viewmodels() call and for this purpose I have to add to build.gradle dependency. But due to the fact that I use ViewModelProvider.Factory it is impossible to use. I tried to inject viewmodel directly in VM class via @HiltViewModel annotation but I got such error:
Injection of an @HiltViewModel class is prohibited since it does not create a ViewModel instance correctly.
Access the ViewModel via the Android APIs (e.g. ViewModelProvider) instead.
Injected ViewModel: pkg.viewModel.AppViewModel
What I can see it that maybe I have to use another injection type which will provide VM for all fragments/dialogfragments and so on but I don't know about it. I have also some test activity on which I can use only:
@Inject
lateinit var viewModel: AppViewModel
and that is all. But I use a lot of fragments in the app so maybe it will be possible to add support for such functionality for fragments too?
Update
my retrofit service:
interface RetrofitService : UserModule {
@POST("login")
suspend fun auth(@Body body: JsonObject): Response<AppAuthModel> // main auth to the app
.....
companion object {
var retrofitService: RetrofitService? = null
fun getInstance(context: Context): RetrofitService {
val client = OkHttpClient.Builder()
.addInterceptor(AppInterceptor(context))
.connectTimeout(100, TimeUnit.SECONDS)
.dispatcher(Dispatcher().apply {
maxRequests = 1
})
.readTimeout(100, TimeUnit.SECONDS).build()
client.dispatcher.cancelAll()
val retrofit = Retrofit.Builder()
.baseUrl(BuildConfig.API_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
retrofitService = retrofit.create(APIService::class.java)
return retrofitService!!
}
}
}
my application class:
@HiltAndroidApp
class BaseApplication:Application()
provider for repository:
@Singleton
@Provides
fun provideApiService(retrofit: Retrofit): RetrofitService =
retrofit.create(RetrofitService::class.java)
@Singleton
@Provides
fun providesRepository(apiService: RetrofitService) = MainRepository(apiService)