I am trying to apply Hilt as a dependency injection framework for my multi module project. I have a module called :app which includes my Application class :
#HiltAndroidApp
class SampleApplication : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
}
}
I have a :feature module which includes my single Activity and Fragments using Navigation architecture component :
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
I can build the project successfully but as soon as it runs on the device, I receive following exception :
Process: com.android.sample.viaplay, PID: 27219
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.sample.viaplay/com.android.sample.viaplay.feature.list.MainActivity}: java.lang.IllegalStateException: Hilt Activity must be attached to an #AndroidEntryPoint Application. Found: class com.android.sample.viaplay.ViaplayApplication
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: Hilt Activity must be attached to an #AndroidEntryPoint Application. Found: class com.android.sample.viaplay.ViaplayApplication
at dagger.hilt.android.internal.managers.ActivityComponentManager.createComponent(ActivityComponentManager.java:83)
at dagger.hilt.android.internal.managers.ActivityComponentManager.generatedComponent(ActivityComponentManager.java:66)
at com.android.sample.viaplay.feature.list.Hilt_MainActivity.generatedComponent(Hilt_MainActivity.java:45)
at com.android.sample.viaplay.feature.list.Hilt_MainActivity.inject(Hilt_MainActivity.java:67)
at com.android.sample.viaplay.feature.list.Hilt_MainActivity$1.onContextAvailable(Hilt_MainActivity.java:38)
at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.java:99)
at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:297)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273)
at androidx.appcompat.app.AppCompatActivity.onCreate(AppCompatActivity.java:115)
at com.android.sample.viaplay.feature.list.MainActivity.onCreate(MainActivity.kt:10)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at
android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
As you see it says : Hilt Activity must be attached to an #AndroidEntryPoint Application.
You can find the source code at : https://github.com/alirezaeiii/Hilt-MultiModule-Cache
I missed to add Hilt plugin and dependencies in build.gradle.kts for feature module :
plugins {
id("commons.android-library")
id(BuildPlugins.HILT)
}
dependencies {
implementation(Dependencies.HILT)
kapt(AnnotationProcessorsDependencies.HILT)
}
object BuildPlugins {
const val HILT = "dagger.hilt.android.plugin"
}
object Dependencies {
const val HILT = "com.google.dagger:hilt-android:${BuildDependenciesVersions.DAGGER}"
object AnnotationProcessorsDependencies {
const val HILT = "com.google.dagger:hilt-android-compiler:${BuildDependenciesVersions.DAGGER}"
}
Related
I'm currently working on a project to practice dependency injection with Dagger-Hilt, however I can't get my ViewModel to instantiate, I've already looked at some other questions on the same topic, most point the issue to Gradle but that didn't fix it for me, all errors in the Stacktrace are from internal classes except for the 2 lines that involve my ViewModel within the MainActivity
Here is the Stacktrace:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.practiceproject, PID: 9873
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.practiceproject/com.example.practiceproject.ui.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.practiceproject.ui.viewmodel.DogViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.practiceproject.ui.viewmodel.DogViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:146)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:111)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at com.example.practiceproject.ui.MainActivity.getDogViewModel(MainActivity.kt:15)
at com.example.practiceproject.ui.MainActivity.onCreate(MainActivity.kt:22)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.practiceproject.ui.viewmodel.DogViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:146)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:111)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at com.example.practiceproject.ui.MainActivity.getDogViewModel(MainActivity.kt:15)
at com.example.practiceproject.ui.MainActivity.onCreate(MainActivity.kt:22)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Here is the ViewModel:
class DogViewModel #Inject constructor(
private val getDefaultImages: GetDefaultImages
) : ViewModel() {
val dogModel = MutableLiveData<DogModel>()
val isLoading = MutableLiveData<Boolean>()
fun onCreate() {
viewModelScope.launch {
isLoading.value = true
val result = getDefaultImages()
if(!result.isNullOrEmpty()) {
dogModel.value = result[0]
isLoading.value = false
}
}
}
And this is where I'm declaring it:
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val dogViewModel: DogViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
dogViewModel.onCreate()
dogViewModel.dogModel.observe(this) {
initRecyclerView(it)
}
}
You should add #HiltViewModel annotation on top of your view model.
Make sure you have written #AndroidEntryPoint above your Fragment or Activity class.
You have to write #HiltViewModel above your ViewModel Class.
Also make sure you are providing all the dependencies written in ViewModel like repositories, etc.
If don't use getDefaultImages object in DogViewModel you can remove it and it will work. If you use it you need to pass an instance of GetDefaultImages class to the DogViewModel using ViewModelProvider.Factory:
#Suppress("UNCHECKED_CAST")
private val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return DogViewModel(GetDefaultImages()) as T
}
}
private val dogViewModel: MyViewModel by viewModels { factory }
This question already has answers here:
Android room persistent: AppDatabase_Impl does not exist
(29 answers)
Closed 12 months ago.
I am working on a notes application with room and ViewModel but while initializing the ViewModel inside activity, I am getting this
java.lang.RuntimeException: Cannot create an instance of class package.notes.homeScreen.HomeScreenVM
here is my main activity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: HomeScreenVM
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setUI()
setViewModel()
}
private fun setUI() {
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
private fun setViewModel() {
viewModel = ViewModelProvider(this, HomeScreenViewModelFactory(this.application))[HomeScreenVM::class.java]
}
}
and ViewModel is like-
class HomeScreenVM(application: Application) : AndroidViewModel(application) {
//some methods
}
and my viewmodelfactory is like-
class HomeScreenViewModelFactory(private val application: android.app.Application) : ViewModelProvider.AndroidViewModelFactory(application) {
#Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(HomeScreenVM::class.java))
return HomeScreenVM(application) as T
throw IllegalArgumentException("Unknown model class")
}
}
I don't know where the problem is. Help me.
Thanks in advance.
Update:-
full stacktrace is
Process: com.nitkkr.sanjay.notes, PID: 32750
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nitkkr.sanjay.notes/com.nitkkr.sanjay.notes.homeScreen.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.nitkkr.sanjay.notes.homeScreen.HomeScreenVM
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3536)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3708)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2143)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8087)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.nitkkr.sanjay.notes.homeScreen.HomeScreenVM
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:315)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:273)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:182)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:151)
at com.nitkkr.sanjay.notes.homeScreen.MainActivity.setViewModel(MainActivity.kt:29)
at com.nitkkr.sanjay.notes.homeScreen.MainActivity.onCreate(MainActivity.kt:17)
at android.app.Activity.performCreate(Activity.java:8157)
at android.app.Activity.performCreate(Activity.java:8129)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3509)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3708)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2143)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8087)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:307)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:273)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:182)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:151)
at com.nitkkr.sanjay.notes.homeScreen.MainActivity.setViewModel(MainActivity.kt:29)
at com.nitkkr.sanjay.notes.homeScreen.MainActivity.onCreate(MainActivity.kt:17)
at android.app.Activity.performCreate(Activity.java:8157)
at android.app.Activity.performCreate(Activity.java:8129)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3509)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3708)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2143)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8087)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: java.lang.RuntimeException: cannot find implementation for com.nitkkr.sanjay.notes.data.database.NoteDatabase. NoteDatabase_Impl does not exist
at androidx.room.Room.getGeneratedImplementation(Room.java:100)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1486)
at com.nitkkr.sanjay.notes.data.database.NoteDatabase$Companion.getInstance(NoteDatabase.kt:24)
at com.nitkkr.sanjay.notes.data.database.NoteRepository.<init>(NoteRepository.kt:11)
at com.nitkkr.sanjay.notes.homeScreen.HomeScreenVM.<init>(HomeScreenVM.kt:12)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:307)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:273)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:182)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:151)
at com.nitkkr.sanjay.notes.homeScreen.MainActivity.setViewModel(MainActivity.kt:29)
at com.nitkkr.sanjay.notes.homeScreen.MainActivity.onCreate(MainActivity.kt:17)
at android.app.Activity.performCreate(Activity.java:8157)
at android.app.Activity.performCreate(Activity.java:8129)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3509)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3708)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2143)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8087)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
viewModel =ViewModelProvider(
this,
HomeScreenViewModelFactory(application)
).get(HomeScreenVM::class.java)
Use this i hope it will work.
I created Viewmodel instance and it worked few times, now it is showing error while initializing userPermissionViewModel in MainActivity.
I am using DataStore to save data and try to observer the same.
I even tried initializing as below, but no luck
userPermissionsViewModel = ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(this.application)).get(UserPermissionsViewModel::class.java)
Error Log
2020-12-11 16:13:40.785 13161-13161/com.lobostaffing.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.lobostaffing.app, PID: 13161
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lobostaffing.app/com.lobostaffing.app.mvvm.ui.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.lobostaffing.app.mvvm.viewmodels.UserPermissionsViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.lobostaffing.app.mvvm.viewmodels.UserPermissionsViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.lobostaffing.app.mvvm.ui.MainActivity.onCreate(MainActivity.kt:231)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.InstantiationException: java.lang.Class<com.lobostaffing.app.mvvm.viewmodels.UserPermissionsViewModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.lobostaffing.app.mvvm.ui.MainActivity.onCreate(MainActivity.kt:231)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
MainActivity.kt
userPermissionsViewModel = ViewModelProvider(this).get(UserPermissionsViewModel::class.java)
userPermissionsViewModel.readFromDataStore.observe(this, { userDetailModel ->
setupNavDrawer(userDetailModel)
})
UserPermissionsViewModel.kt
class UserPermissionsViewModel(application: Application): ViewModel() {
private val userPermissionsRepo = UserPermissionsRepo(application)
val readFromDataStore = userPermissionsRepo.userDetailModel.asLiveData()
fun saveToDataStore(userDetailModel: UserDetailModel) = viewModelScope.launch(Dispatchers.IO){
userPermissionsRepo.saveUserPermissions(userDetailModel)
}}
Build.gradle
def archLifecycleVersion = '2.2.0'
//Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$archLifecycleVersion"
Try this
MainActivity:
class MainActivity : AppCompatActivity() {
private lateinit var userPermissionsViewModel: UserPermissionsViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
userPermissionsViewModel = ViewModelProvider(this).get(UserPermissionsViewModel::class.java)
}
}
And your viewModel:
class UserPermissionsViewModel(application: Application) : AndroidViewModel(application) {
private val userPermissionsRepo = UserPermissionsRepo(application)
}
Initialize your viewmodel like this
yourViewModelInstance = new ViewModelProvider(this).get(YourViewModelClass.class);
When you need an application context in the ViewModel it should extend AndroidViewModel.
ViewModel with context:
class UserPermissionsViewModel(application: Application) : AndroidViewModel(application)
or without context
class UserPermissionsViewModel : ViewModel()
When a regular ViewModel has any constructor paramaters, the default ViewModelFactory does not know how to create it.
Try to add the right dependencies
//lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
I migrated my app from dagger2 to hilt manually. i didn't face any compilation or build errors.
but when I try to run my app, it crashes at the splash screen with this stack:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: pfe.usdb.dictili, PID: 7815
java.lang.RuntimeException: Unable to start activity ComponentInfo{pfe.usdb.dictili/pfe.usdb.dictili.view.auth.SplashScreen}: java.lang.RuntimeException: Cannot create an instance of class pfe.usdb.dictili.viewmodel.auth.AuthVModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.RuntimeException: Cannot create an instance of class pfe.usdb.dictili.viewmodel.auth.AuthVModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
at androidx.hilt.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:74)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at pfe.usdb.dictili.view.auth.SplashScreen.getViewModel(Unknown Source:2)
at pfe.usdb.dictili.view.auth.SplashScreen.onCreate(SplashScreen.kt:46)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.InstantiationException: java.lang.Class<pfe.usdb.dictili.viewmodel.auth.AuthVModel> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
at androidx.hilt.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:74)
at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at pfe.usdb.dictili.view.auth.SplashScreen.getViewModel(Unknown Source:2)
at pfe.usdb.dictili.view.auth.SplashScreen.onCreate(SplashScreen.kt:46)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
it says it cannot create an instance of that viewmodel because it doesn't have a zero argument constructor, but:
1- my viewmodel class is injected with hilt (BaseViewModel is abstract):
class AuthVModel #ViewModelInject constructor(
private val sharedPreferences: PreferencesRepository,
private val authRepository: AuthRepository
) : BaseViewModel()
2- my activity is annotated with AndroidEntryPoint (BaseActivity is abstract):
#AndroidEntryPoint
class SplashScreen : BaseActivity() {
private val viewModel: AuthVModel by viewModels()
3- the repositories the viewmodel is depending on are injected properly and android studio 4.1.1 is showing the injection icon on the left:
class AuthRepository #Inject constructor(
#NonAuthenticatedAuthenticationService private val unauthorizedService: AuthService,
#AuthenticatedAuthenticationService private val authorizedService: AuthService
)
class PreferencesRepository #Inject constructor(
private val sharedPreferences: SharedPreferences
)
I don't know what's happening here, this is not my first time working with this, since I built some apps recently just like this (some code is 100% copied from these projects).
Did you use the required dependency for jetpack components (ViewModel in your case) in your module's gradle.build file?
Namely:
kapt "androidx.hilt:hilt-compiler:$hiltJetpackVer"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hiltJetpackVer"
Note that the version is different than the one used for the main hilt dependency.
The code is working fine without Proguard Rule setup. But when I enabled proguard in release build, The project is build successfully. App is installed successfully but while launching the app it crashed every time .
Here is the error log
2018-10-29 13:52:04.299 1942-1942/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.eighsquare.mcoopon, PID: 1942
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.eighsquare.mcoopon/com.eighsquare.mcoopon.ui.splash.SplashActivity}: java.lang.RuntimeException: Cannot create an instance of class com.eighsquare.mcoopon.ui.splash.a
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.eighsquare.mcoopon.ui.splash.a
at androidx.lifecycle.v$a.a(ViewModelProvider.java:202)
at androidx.lifecycle.v.a(ViewModelProvider.java:135)
at androidx.lifecycle.v.a(ViewModelProvider.java:103)
at com.eighsquare.mcoopon.base.BaseActivity$b.b(**BaseActivity.kt**:32)
at com.eighsquare.mcoopon.base.BaseActivity$b.a(BaseActivity.kt:16)
at kotlin.o.a(LazyJVM.kt:74)
at com.eighsquare.mcoopon.base.BaseActivity.q(Unknown Source:7)
at com.eighsquare.mcoopon.base.BaseActivity.onCreate(BaseActivity.kt:50)
at android.app.Activity.performCreate(Activity.java:7009)
at android.app.Activity.performCreate(Activity.java:7000)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NoSuchMethodException: <init> [class android.app.Application]
at java.lang.Class.getConstructor0(Class.java:2320)
at java.lang.Class.getConstructor(Class.java:1725)
at androidx.lifecycle.v$a.a(ViewModelProvider.java:200)
at androidx.lifecycle.v.a(ViewModelProvider.java:135)
at androidx.lifecycle.v.a(ViewModelProvider.java:103)
at com.eighsquare.mcoopon.base.BaseActivity$b.b(BaseActivity.kt:32)
at com.eighsquare.mcoopon.base.BaseActivity$b.a(BaseActivity.kt:16)
at kotlin.o.a(LazyJVM.kt:74)
at com.eighsquare.mcoopon.base.BaseActivity.q(Unknown Source:7)
at com.eighsquare.mcoopon.base.BaseActivity.onCreate(BaseActivity.kt:50)
at android.app.Activity.performCreate(Activity.java:7009)
at android.app.Activity.performCreate(Activity.java:7000)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
when I click on the BaseActivity.kt I am redirected to this code
val viewModel by lazy {
if (viewModelFactory != null)
ViewModelProviders.of(this, viewModelFactory).get(mViewModelClass)
else ViewModelProviders.of(this).get(mViewModelClass)
}
This code is placed in the BaseActivity to create Viewmodel.
Here is My BaseActivity.kt
abstract class BaseActivity<VM : ViewModel, DB : ViewDataBinding>(private val mViewModelClass: Class<VM>) : AppCompatBaseActivity() {
#LayoutRes
abstract fun getLayoutRes(): Int
abstract val viewModelFactory: ViewModelProvider.Factory?
val binding by lazy {
DataBindingUtil.setContentView(this, getLayoutRes()) as DB
}
val viewModel by lazy {
if (viewModelFactory != null)
ViewModelProviders.of(this, viewModelFactory).get(mViewModelClass)
else ViewModelProviders.of(this).get(mViewModelClass)
}
/**
* If you want to inject Dependency Injection
* on your activity, you can override this.
*/
open fun onInject() {}
open fun initView() {}
override fun onCreate(savedInstanceState: Bundle?) {
onInject()
LayoutInflaterCompat.setFactory2(layoutInflater, IconicsLayoutInflater2(delegate))
super.onCreate(savedInstanceState)
initViewModel(viewModel)
initView()
}
/**
*
* You need override this method.
* And you need to set viewModel to binding: binding.viewModel = viewModel
*
*/
abstract fun initViewModel(viewModel: VM)
fun isNetworkConnected(): Boolean {
return NetworkUtils.isNetworkConnected(this)
}
fun hideKeyboard() {
Utils.hideKeyboard(this)
}
fun changeFragment(fragment: Fragment, cleanStack: Boolean = false, addToBackStack: Boolean = true) {
Utils.changeFragment(this, fragment, cleanStack, addToBackStack)
}
}
I am using Dagger2
I lost my 2 hrs in searching the solution. Stackoverflow is the last hope.
After a long research I got a solution.
I Simply needed to add public #Inject constructor in my ViewModel class
eg;
class FullScreenViewModel public #Inject constructor(application: Application) : BaseViewModel<Any?>(application) {}