SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class<T>, extras: CreationExtras)
See original GitHub issueI am getting SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class, extras: CreationExtras)
errors when createBiometricPrompt()
is called in the code below:
@HiltAndroidApp
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Logging
Timber.plant(Timber.DebugTree())
}
}
@OptIn(
ExperimentalAnimationApi::class,
ExperimentalMaterialApi::class,
ExperimentalComposeUiApi::class,
ExperimentalFoundationApi::class
)
@AndroidEntryPoint
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
MyTheme() {
ProvideWindowInsets {
Navigation()
}
}
}
}
@OptIn(
ExperimentalAnimationApi::class,
ExperimentalMaterialApi::class,
ExperimentalComposeUiApi::class,
ExperimentalFoundationApi::class
)
@Composable
fun Navigation(
// other params...
authViewModel: AuthViewModel = hiltViewModel(),
// other params...
) {
Root( ) { scaffoldState, coroutineScope ->
AnimatedNavHost(
navController = navController,
startDestination = //...
) {
composable(route = Screen.Auth.name) {
// fixme: this crashes with `SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class, extras: CreationExtras)`
BiometricPromptDialog(
biometricPrompt = authViewModel.createBiometricPrompt(
activity = LocalContext.current as FragmentActivity,
onSuccess = {
navController.navigate(/* some screen */) {
// remove biometric screen from back stack
popUpTo(/* some screen *) {
inclusive = true
}
}
}
),
// other params...
}
// other composable()
}
}
}
@HiltViewModel
class AuthViewModel @Inject constructor(
@BiometricSupported isBiometricAuthSupported: Boolean,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
private val preferenceDataStore: PreferenceDataStore
) : ViewModel() {
// other code...
fun createBiometricPrompt(
activity: FragmentActivity,
onSuccess: (BiometricPrompt.AuthenticationResult) -> Unit
): BiometricPrompt {
val executor = ContextCompat.getMainExecutor(activity)
val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errCode: Int, errString: CharSequence) {
super.onAuthenticationError(errCode, errString)
Timber.e("Error authenticating. Code $errCode ($errString")
promptState = BiometricPromptState.ERROR
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
Timber.e("Biometric authentication failed.")
promptState = BiometricPromptState.FAIL
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
Timber.d("Authentication successful")
promptState = BiometricPromptState.SUCCESS
onSuccess(result)
}
}
return BiometricPrompt(activity, executor, callback)
}
}
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.1.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
classpath("com.google.dagger:hilt-android-gradle-plugin:2.40.5"
}
}
tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
plugins {
id("com.android.application")
kotlin("android")
id("kotlin-parcelize")
kotlin("kapt")
id("dagger.hilt.android.plugin")
id("com.google.protobuf") version "0.8.12"
id("com.mikepenz.aboutlibraries.plugin") version "10.0.0-b08"
}
dependencies {
// other dependencies...
implementation("com.google.dagger:hilt-android:2.40.5")
kapt("com.google.dagger:hilt-compiler:2.40.5}")
kapt("androidx.hilt:hilt-compiler:1.0.0")
implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03")
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
// other dependencies...
}
The error occurs also when creating an instance of AuthViewModel
in MainActivity
and passing it down as a parameter to Navigation()
(instead of using hiltViewModel()
)
private val authViewModel by viewModels<AuthViewModel>()
Can’t seem to figure this one out. What step can I take to find the source of the issue? Any pointer is appreciated, thanks!
Full crash log:
2022-02-06 22:35:29.957 31668-31668/com.my.package E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.my.package, PID: 31668
java.lang.UnsupportedOperationException: SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class<T>, extras: CreationExtras).
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:165)
at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:220)
at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:111)
at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.kt:79)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:168)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:137)
at androidx.biometric.BiometricPrompt.getViewModel(BiometricPrompt.java:1029)
at androidx.biometric.BiometricPrompt.<init>(BiometricPrompt.java:847)
at com.my.package.viewmodel.AuthViewModel.createBiometricPrompt(AuthViewModel.kt:105)
at com.my.package.navigation.NavigationKt$Navigation$13$1$1.invoke(Navigation.kt:165)
at com.my.package.navigation.NavigationKt$Navigation$13$1$1.invoke(Navigation.kt:162)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9$1.invoke(AnimatedNavHost.kt:212)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9$1.invoke(AnimatedNavHost.kt:210)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(SaveableStateHolder.kt:84)
at androidx.navigation.compose.NavBackStackEntryProviderKt.SaveableStateProvider(NavBackStackEntryProvider.kt:60)
at androidx.navigation.compose.NavBackStackEntryProviderKt.access$SaveableStateProvider(NavBackStackEntryProvider.kt:1)
at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:52)
at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:51)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.navigation.compose.NavBackStackEntryProviderKt.LocalOwnersProvider(NavBackStackEntryProvider.kt:47)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9.invoke(AnimatedNavHost.kt:210)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9.invoke(AnimatedNavHost.kt:202)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1$4.invoke(AnimatedContent.kt:658)
at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1$4.invoke(AnimatedContent.kt:648)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.animation.AnimatedVisibilityKt.AnimatedEnterExitImpl(AnimatedVisibility.kt:935)
at androidx.compose.animation.AnimatedVisibilityKt.AnimatedVisibility(AnimatedVisibility.kt:606)
2022-02-06 22:35:29.958 31668-31668/com.my.package E/AndroidRuntime: at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1.invoke(AnimatedContent.kt:638)
at androidx.compose.animation.AnimatedContentKt$AnimatedContent$5$1.invoke(AnimatedContent.kt:625)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.animation.AnimatedContentKt.AnimatedContent(AnimatedContent.kt:671)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:197)
at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:91)
at com.my.package.navigation.NavigationKt$Navigation$13.invoke(Navigation.kt:151)
at com.my.package.navigation.NavigationKt$Navigation$13.invoke(Navigation.kt:150)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at com.my.package.ui.components.RootKt$Root$3$4.invoke(Root.kt:215)
at com.my.package.ui.components.RootKt$Root$3$4.invoke(Root.kt:214)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:142)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2158)
at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2413)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2594)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2580)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:247)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2580)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2556)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:624)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:795)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:106)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:465)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:434)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:947)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:693)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:17 (6 by maintainers)
Top Results From Across the Web
SavedStateViewModelFactory constructed with empty ...
UnsupportedOperationException : SavedStateViewModelFactory constructed with empty constructor supports only calls to create(modelClass: Class, ...
Read more >SavedStateViewModelFactory - Android Developers
ViewModelProvider.Factory that can create ViewModels accessing and contributing to a saved state via SavedStateHandle received in a constructor.
Read more >SavedStateViewModelFactory constructed with empty ...
We have an issue with HiltViewModelFactory. It calls create method without passing new CreationExtras values. I assume this should be fixed in hilt...
Read more >AbstractSavedStateViewModelF...
"AbstractSavedStateViewModelFactory constructed ". + "with empty constructor supports only calls to ". + "create(modelClass: Class<T>, extras: ...
Read more >Class androidx.lifecycle.AbstractSavedStateViewModelFactory
... constructed " + "with empty constructor supports only calls to " + "create(modelClass: Class<T>, extras: CreationExtras).
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hey - Wanted to share an update that a change in androidx is going to fix this issue and if all goes well, it will be available in a future alpha version of androidx’s activity, fragment and viewmodel-savedstate artifacts.
Just wanted to update anyone listening out here. The latest alpha versions (updated March 23) of the relevant androidx libraries fix this particular issue for me 🎉