Reputation: 612
I've tried to hand over a simple viewModel to a composable and get everytime this error and i don't know what it means:
java.lang.IllegalStateException: Given component holder class com.example.app.MainActivity does not implement interface dagger.hilt.internal.GeneratedComponent or interface dagger.hilt.internal.GeneratedComponentManager
My Gradle:
implementation("androidx.hilt:hilt-navigation:1.0.0-beta01")
implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")
I've created a BaseApplication
file
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class BaseApplication: Application()
and set it in the Manifest.
I've created an AppModule
file:
import android.content.Context
import com.veloce.montageservice.BaseApplication
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideApplication(@ApplicationContext app: Context): BaseApplication {
return app as BaseApplication
}
}
Then set the @HiltAndroidApp
in my MainActivity
and created a viewModel
like this:
@HiltViewModel
class TaskViewModel: ViewModel() {
//code
}
The viewModel
is called in my navigation at the MainActivity
:
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Screens.LoginScreen.route
) {
composable(Screens.ActiveMontageScreen.route) { navBackStackEntry ->
activeTask?.let {
val factory =
HiltViewModelFactory(LocalContext.current, navBackStackEntry)
val viewModel: TaskViewModel = viewModel("taskViewModel", factory)
ActiveMontageScreen(
viewModel = viewModel,
task = it,
navigation = navController,
context = LocalContext.current
) {
removeActiveTask()
}
}
}
}
I really cant't see any problems, but I am quite unexperienced with Hilt and Android Development. Does anyone know whats the problem?
Upvotes: 9
Views: 15585
Reputation: 412
Update
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
kapt 'androidx.hilt:hilt-compiler:1.0.0'
Upvotes: 1
Reputation: 2028
please check these options:
1- you must have these dependencies:
//Hilt
def hilt_version = "2.38.1"
implementation("com.google.dagger:hilt-android:$hilt_version")
kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
kapt("androidx.hilt:hilt-compiler:1.0.0")
implementation("androidx.hilt:hilt-navigation-compose:1.0.0-alpha03")
implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")
2- you must have added this annotation into your activity
@AndroidEntryPoint
class MainActivity : ComponentActivity()
3- you must have injected your viewModel in your screen like this
@Composable
fun MainScreen(
viewModel: MainScreenViewModel = hiltViewModel()
)
Upvotes: 7
Reputation: 428
So for you viewmodel, you'll need to add the annotation @Inject or @ViewModelInject depending on your version dependency and create it like this
class TaskViewModel @Inject constructor(context: Context) : ViewModel() {
//code
}
And in your activity of fragment Instantiate this way
val taskViewModel: TaskViewModel by viewmodels()
Upvotes: 0
Reputation: 9073
There are few things misplaced as I can see, which lead to such error.
For example:
You're not injecting the context here class TaskViewModel(context: Context)
if you need context in viewmodel
then you can use AndroidViewModel
.
you're creating BaseApplication
in AppModule
but you're not using it(Maybe used somewhere else).
You can create such viewmodel with following steps:
Create BaseApplication
& register that in manifest, which you have already done.
Create a AndroidViewModel
as following:
@HiltViewModel
class TaskViewModel @Inject constructor(
application: BaseApplication
) : AndroidViewModel(application) {
fun test() {
getApplication<BaseApplication>().getString(R.string.app_name)
}
}
Here notice the use of @Inject constructor
which will take the BaseApplication
class from AppModule
.
In your MainActivity
initialize the viewmodel
like this:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: TaskViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.test()
}
}
If you fail to resolve any of the hilt related things then make sure you have these dependencies in build.gradle
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.33-beta"
kapt "com.google.dagger:hilt-android-compiler:2.33-beta"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"
Upvotes: 4