1
votes

I've been trying to resolve my issue but I can't find anything...

MyApp.kt :

@HiltAndroidApp
class MyApp: Application()

MainActivity.kt

@AndroidEntryPoint
class MainActivity: AppCompatActivity() 

MyFragment.kt

class MyFragment: Fragment() {
    private val myViewModel: MyViewModel by viewModels()
}

MyViewModel.kt

class MyViewModel @ViewModelInject constructor(
    application: Application,
    myRepository: MyRepository, {*}
    @Assisted private val state: SavedStateHandle,
): AndroidViewModel(application)

MyRepository.kt

interface MyRepository { 
    fun test()
}

class MyRepositoryImpl @Inject constructor(): MyRepository { 
    override fun test() { print("") }
}

MyModule.kt

@Module 
@InstallIn(SingletonComponent::class)
abstract class MyModule {
    @Binds
    abstract fun bindsMyRepository(impl: MyRepositoryImpl): MyRepository
}

If I comment the line with "{*}", it works fine, but since I try to add my custom repository, I got this error :

java.lang.RuntimeException: Cannot create an instance of class MyViewModel

Caused by: java.lang.NoSuchMethodException: [class android.app.Application]

Do you have any idea of what I am missing?

Thanks you!

Complementary informations: I forgot to mention that this is a multi module app.

In the first module, there is the basic app : MainActivity, a manifest (1)

In the second module, there is the core app : MyApp, a manifest (2)

In the third module, there is the module : MyFragment, MyViewModel, MyRepository and MyModule, a manifest (3)

Manifests are like this:

(1)

<manifest...>
    <application...
        android:name=".secondModule.MyApp">
</manifest>

(2)

<manifest...>
    <application>
        <provider...></provider>
    </application>
</manifest>

(3)

<manifest.../>
2
what do you need the interface for ? - Taki
I have simplify as much as I can my code :) I have a repository which calls an Api class, but for now I have remove it until it works - JohnDoe
You'll need to add some build.gradle dependencies because this sounds like Dagger + Hilt version mismatch. - EpicPandaForce
My current version (after IR42 answer) : Dagger : 2.31.1, Hilt : 2.31-alpha - JohnDoe

2 Answers

0
votes
  • First Annotate your fragment
@AndroidEntryPoint
 class MyFragment: Fragment() {
  private val myViewModel: MyViewModel by viewModels()
}
  • Secondly you have to extend ViewModel instead of AndroidViewModel
class MyViewModel @ViewModelInject constructor(
   @Application context : Context ,
   myRepository: MyRepository, {*}
   @Assisted private val state: SavedStateHandle,
): ViewModel()
  • Subsitute SingletonComponent With ApplicationComponent
 @Module 
@InstallIn(ApplicationComponent::class)
abstract class MyModule {
    @Binds
    abstract fun bindsMyRepository(impl: MyRepositoryImpl): MyRepository
}

PS : Don't forget to add your application class( MyApp ) to your manifest file

0
votes

You must use @AndroidEntryPoint for your fragments

@AndroidEntryPoint
class MyFragment: Fragment() {
    private val myViewModel: MyViewModel by viewModels()
}

Also ApplicationComponent was removed in Dagger 2.30, but it is used in androidx.hilt:hilt (@ViewModelInject). They added ApplicationComponent back in 2.31.1 because of the library mentioned above.

Update your Dagger version to 2.31.1 (use SingletonComponent instead of ApplicationComponent) or use new feature Hilt View Models

@HiltViewModel
class MyViewModel @Inject constructor(
    private val application: Application,
    myRepository: MyRepository,
    private val state: SavedStateHandle,
): ViewModel()