Closed garethbowen closed 2 months ago
Updates: Putting this on pause status for the time being as this issue seems to be a bit more time-consuming than initially assumed. I'll pick up this issue once I have finished my current ongoing tasks in the app services team. So far my attempts to recreate this issue have been unsuccessful. I've tried this on a wide range of devices, both Android Studio emulators and physical devices, in various Android versions. Things to do when resuming this:
I've had a look through the stacktrace. All search results are coming back saying every fragment needs a public empty constructor. This is confirmed by the docs: https://developer.android.com/reference/android/app/Fragment.html#Fragment()
Default constructor. Every fragment must have an empty constructor, so it can be instantiated when restoring its activity's state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated; instead, arguments can be supplied by the caller with setArguments(Bundle) and later retrieved by the Fragment with [getArguments()](https://developer.android.com/reference/android/app/Fragment#getArguments()).
Applications should generally not implement a constructor. Prefer onAttach(android.content.Context) instead. It is the first place application code can run where the fragment is ready to be used - the point where the fragment is actually associated with its context. Some applications may also want to implement onInflate(Activity, AttributeSet, Bundle) to retrieve attributes from a layout resource, although note this happens when the fragment is attached.
Following this thread and I noticed that the EmbeddedBrowserActivity.onCreate method that's throwing the Exception does set up the OpenSettingsDialogFragment here.
If you go to the OpenSettingsDialogFragment source you will in fact see we specify a constructor with args and do not have a default public no arg constructor.
So I think this is the smoking gun - we're doing exactly what the docs say we must not do. Funnily enough we're even suppressing the lint error that would have picked this up.
There's even a hint about how to reproduce this in this line of the docs...
It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated
What I think might be happening is the app is returning from some sort of hibernation state and Android is reconstructing this Fragment and finding no constructor for it to call. This is still quite hard to reproduce because I don't know how to force an app into hibernation, but it's a start. Maybe there's a way in the emulator to force it?
Anyway, my approach to fix this would be...
onTouch
call is in the EmbeddedBrowserActivity and calls a method on the OpenSettingsDialogFragment? I think this would be cleaner so we're not holding on to a copy of the view, but it's also more work to refactor.@sugat009 Does that all make sense? Can you start on this list without necessarily reproducing the issue yourself?
@garethbowen Thanks for such a detailed investigation and explanation. I'll pick this up after my work in the app services team is done.
Describe the bug Play Store is reporting the "Medic" android app is crashing for 15% of users many with a
android.app.Fragment$InstantiationException
. The Medic app isn't "production" but we should investigate to ensure this doesn't impact anyone else, and prioritise accordingly.To Reproduce Not sure how to reproduce it.
Expected behavior No crashes.
Logs
Environment
Additional context More info here: https://play.google.com/console/developers/7987044497930745454/app/4973604959552855131/vitals/crashes?errorType=CRASH&appProcessState=Foreground&days=28