BiometricPrompt crashes the app on rotation / onCreate - android

I want to use biometric (fingerprint) login as soon as the app launches.
The app uses a hosting activity and loads the login fragment with biometrics (androidx.biometric:biometric:1.2.0-alpha03). Everything regarding the login works fine but as soon as the phone rotates it crashes. From the log file I understand that the crash happens inside the onCreate because it tries to recreate the FingerprintDialogFragment with an empty constructor.
I tried to cancel the authentication in the onPause function and recreate it manually but that doesn't help. So far my code inside the fragment looks like this:
override fun onResume() {
super.onResume()
if(loginSharedPreferences.getBoolean(BIOMETRIC_SET, false)) {
setupBiometricPrompt()
biometricPrompt?.authenticate(promptInfo)
}
}
override fun onPause() {
if(biometricPrompt != null) {
biometricPrompt!!.cancelAuthentication()
biometricPrompt = null
}
super.onPause()
}
private fun setupBiometricPrompt() {
promptInfo = createBiometricPromptInfo()
executor = ContextCompat.getMainExecutor(requireContext())
biometricPrompt = BiometricPrompt(this, executor,
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int,
errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
Log.d(TAG, "Authentication error: $errString")
}
override fun onAuthenticationSucceeded(
result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
Log.d(TAG, "Authentication succeeded!")
callbacks?.loginSuccessful()
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
Log.d(TAG, "Authentication failed!")
}
})
}
private fun createBiometricPromptInfo(): BiometricPrompt.PromptInfo {
return BiometricPrompt.PromptInfo.Builder()
.setTitle(resources.getString(R.string.biometric_title))
.setSubtitle(resources.getString(R.string.biometric_subtitle))
.setNegativeButtonText(resources.getString(R.string.biometric_cancel))
.setAllowedAuthenticators(BIOMETRIC_STRONG)
.build()
}
And the log file:
java.lang.RuntimeException: Unable to start activity: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment androidx.biometric.FingerprintDialogFragment: could not find Fragment constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment androidx.biometric.FingerprintDialogFragment: could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(Fragment.java:628)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:483)
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)
at androidx.fragment.app.FragmentManager.restoreSaveState(FragmentManager.java:2728)
at androidx.fragment.app.Fragment.restoreChildFragmentState(Fragment.java:1890)
at androidx.fragment.app.Fragment.onCreate(Fragment.java:1867)
at com.tetraguard.android.otp.LoginPinFragment.onCreate(LoginPinFragment.kt:59)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2949)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:3061)
at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:240)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:276)
at com.tetraguard.android.otp.MainActivity.onCreate(MainActivity.kt:61)
at android.app.Activity.performCreate(Activity.java:7327)
at android.app.Activity.performCreate(Activity.java:7318)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948) 
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7050) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 
Caused by: java.lang.NoSuchMethodException: androidx.biometric.FingerprintDialogFragment.<init> []
at java.lang.Class.getConstructor0(Class.java:2328)
at java.lang.Class.getConstructor(Class.java:1725)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:613)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57) 
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:483) 
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85) 
at androidx.fragment.app.FragmentManager.restoreSaveState(FragmentManager.java:2728) 
at androidx.fragment.app.Fragment.restoreChildFragmentState(Fragment.java:1890) 
at androidx.fragment.app.Fragment.onCreate(Fragment.java:1867) 
at com.tetraguard.android.otp.LoginPinFragment.onCreate(LoginPinFragment.kt:59) 
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2949) 
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475) 
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278) 
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112) 
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647) 
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128) 
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:3061) 
at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:240) 
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:276) 
at com.tetraguard.android.otp.MainActivity.onCreate(MainActivity.kt:61) 
at android.app.Activity.performCreate(Activity.java:7327) 
at android.app.Activity.performCreate(Activity.java:7318) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948) 
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7050) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

This issue has been reported to the Google issue tracker. Might be better to follow the discussion here:
https://issuetracker.google.com/issues/181805603

Related

Unable to create androidviewmodel instance [duplicate]

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.

Android : WindowInsetsAnimationCallback error during exec

I'm trying to know when the animation close of the softkeyboard is done. So i try to use this function :
val rootLayout = findViewById<ConstraintLayout>(R.id.root_layout)
rootLayout.setWindowInsetsAnimationCallback(object : WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
override fun onProgress(insets: WindowInsets, runningAnimations: MutableList<WindowInsetsAnimation>): WindowInsets {
//TODO("Not yet implemented")
return insets
}
override fun onEnd(animation: WindowInsetsAnimation) {
super.onEnd(animation)
val showingKeyboard = rootLayout.rootWindowInsets.isVisible(WindowInsets.Type.ime())
if (!showingKeyboard) {
println("Keyboard is now closed")
}
}
})
but when i launch the app on my phone (and several emu) i have to face to this error :
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/view/WindowInsetsAnimation$Callback;
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1251)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3222)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3459)
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:2046)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:225)
at android.app.ActivityThread.main(ActivityThread.java:7564)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.WindowInsetsAnimation$Callback" on path: DexPathList[[zip file "/data/app/com.example.buginsetsanimationlistener-wRvK7cMTAxdBF1RCG19tlA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.buginsetsanimationlistener-wRvK7cMTAxdBF1RCG19tlA==/lib/arm64, /system/lib64, /system/product/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:230)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at java.lang.Class.newInstance(Native Method) 
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95) 
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45) 
at android.app.Instrumentation.newActivity(Instrumentation.java:1251) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3222) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3459) 
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:2046) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:225) 
at android.app.ActivityThread.main(ActivityThread.java:7564) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 
I don't understand what i should do, thanks for your answers !
I finally found my mystake. this method is for API 30+. But i've found another way to achieve my goal :
This is work when i close by myself the soft keyboard.
imm.hideSoftInputFromWindow(rootLayout.windowToken, 0, object : ResultReceiver(null) {
override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
if (resultCode == InputMethodManager.RESULT_UNCHANGED_HIDDEN ||
resultCode == InputMethodManager.RESULT_HIDDEN) {
//Soft has finished the animation
}
}
}
})
Hope this answer help someone :)

Cannot create an instance of class ViewModel in Android MVVM

I am learning android MVVM pattern android development. I wanted to create a recycclerview activity to show data from server. But it's not accepting my viewmodel class. Bellow is my logcat errors.
LOGCAT
2020-04-12 21:03:18.026 2008-2008/com.shovon.mvvm E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shovon.mvvm, PID: 2008
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shovon.mvvm/com.shovon.mvvm.activity.RecyclerActivity}: java.lang.RuntimeException: Cannot create an instance of class com.shovon.mvvm.viewmodel.RecyclerActivityViewModel
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.shovon.mvvm.viewmodel.RecyclerActivityViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.shovon.mvvm.activity.RecyclerActivity.onCreate(RecyclerActivity.kt:23)
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.shovon.mvvm.viewmodel.RecyclerActivityViewModel> 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.get(ViewModelProvider.java:187) 
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
at com.shovon.mvvm.activity.RecyclerActivity.onCreate(RecyclerActivity.kt:23) 
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) 
VIEWMODEL
Here is my viewmodel class. I am passing some data to activity from this viewmodel. But problem is activity does not accept this viewmodel. Maybe viewmodel has any issue.
class RecyclerActivityViewModel(application: Application) : AndroidViewModel(application) {
val repository = RecyclerActivityRepository(application)
fun userData(): LiveData<ArrayList<UserResponse>>{
return repository.getUserData()
}
}
REPOSITORY
class RecyclerActivityRepository(application: Application) {
var liveData = MutableLiveData<ArrayList<UserResponse>>()
private val userList = ArrayList<UserResponse>()
private var adapter: UserAdapter? = null
fun getUserData(): MutableLiveData<ArrayList<UserResponse>>{
if (liveData == null){
liveData = MutableLiveData<ArrayList<UserResponse>>()
}
RetrofitClient.instance.getUsers()
.enqueue(object : Callback<List<UserResponse>> {
override fun onFailure(call: Call<List<UserResponse>>, t: Throwable) {
Log.v("Retrofit", t.message.toString())
}
override fun onResponse(
call: Call<List<UserResponse>>,
response: Response<List<UserResponse>>
) {
Log.v("Retrofit", "Success")
Log.v("response_code", response.code().toString())
try {
userList.addAll(response.body()!!)
adapter?.notifyDataSetChanged()
}catch (e: Exception){
Log.v("error", e.message.toString())}
}
})
return liveData
}
}
ACTIVITY
Here is my logic code
class RecyclerActivity : AppCompatActivity() {
private lateinit var viewModel: RecyclerActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recycler)
viewModel = ViewModelProvider(this).get(RecyclerActivityViewModel::class.java)
}
}
this might help
viewModel= ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(RecyclerActivityViewModel::class.java)

Cannot create instance of ViewModel class

I'm doing this inside my onCreate method of MainActivity
journalViewModel = new ViewModelProvider(this).get(JournalViewModel.class);
and my ViewModel is as following:
public class JournalViewModel extends AndroidViewModel {
public JournalViewModel(#NonNull Application application) {
super(application);
repository = new JournalRepository(application);
journals = repository.getAllJournals();
}
}
However, I'm getting the error for this line,
journalViewModel = new ViewModelProvider(this).get(JournalViewModel.class);
saying,
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.diaryapp/com.example.diaryapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.diaryapp.JournalViewModel
As per my knowledge the constructor inside ViewModel shouldn't have any other parameter except the one in my code and both constructor and class should be public.
However, further inside my error logs, I get the error:
java.lang.InstantiationException: java.lang.Class<com.example.diaryapp.JournalViewModel> has no zero argument constructor
Here's the complete error log:
2020-03-23 21:37:18.986 8632-8632/com.example.diaryapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.diaryapp, PID: 8632
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.diaryapp/com.example.diaryapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.diaryapp.JournalViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.diaryapp.JournalViewModel
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.diaryapp.MainActivity.onCreate(MainActivity.java:40)
at android.app.Activity.performCreate(Activity.java:7224)
at android.app.Activity.performCreate(Activity.java:7213)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:201) 
at android.app.ActivityThread.main(ActivityThread.java:6823) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.diaryapp.JournalViewModel> 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.get(ViewModelProvider.java:187) 
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
at com.example.diaryapp.MainActivity.onCreate(MainActivity.java:40) 
at android.app.Activity.performCreate(Activity.java:7224) 
at android.app.Activity.performCreate(Activity.java:7213) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:201) 
at android.app.ActivityThread.main(ActivityThread.java:6823) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
You should obtain JournalViewModel like:
journalViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(JournalViewModel.class);
instead of
journalViewModel = new ViewModelProvider(this).get(JournalViewModel.class);
Not sure about Java, but this worked for me in Kotlin.
You need to define a ViewModelProvidor.Factory:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModelFactory.setApplication(application)
val journalViewModel = ViewModelProvider(this, viewModelFactory).get(JournalViewModel::class.java)
}
}
object viewModelFactory : ViewModelProvider.Factory {
lateinit var app : Application
fun setApplication(application: Application) {
app = application
}
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return JournalViewModel(app) as T
}
}
I got it working with the help of this answer.
Here's what I did in,
JournalFactory.java
public class JournalFactory extends ViewModelProvider.NewInstanceFactory {
private Application application;
public JournalFactory(#NonNull Application application) {
this.application = application;
}
#NonNull
#Override
public <T extends ViewModel> T create(#NonNull Class<T> modelClass) {
if (modelClass == JournalViewModel.class)
return (T) new JournalViewModel(application);
return null;
}
}
onCreate() method of MainActivity.java
journalViewModel = new ViewModelProvider(this, new JournalFactory(getApplication())).get(JournalViewModel.class);

Proguard rule setup for mvvm

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) {}

Categories

Resources