Fixed
Status Update
Comments
ko...@gmail.com <ko...@gmail.com> #2
It's not just EditTextPreference related problem, just to clarify things. ListPreference throws the same exception.
ch...@google.com <ch...@google.com>
ni...@google.com <ni...@google.com> #3
That stack trace implies that the preference that the dialog is based on couldn't be found. That could happen for obvious reasons (not loading the correct set of preference items in onCreatePreferences) or for subtle reasons (fragments getting onCreate called in an unexpected order).
ch...@utildata.de <ch...@utildata.de> #4
This only appears on a specific order of adding Fragment instances and making them active in an Activity. I mean there are chances to not get the exception. The problem lies in the mActive List of active Fragment instances in the FragmentManager of the Activity. When restoring the state of the Activity on orientation change, in some cases the child PreferenceDialogFragmentCompat is created before the parent/target Fragment's onCreate() got called (if its position index in mActive List is lower). So the preference (requested in the onCreate() of the PreferenceDialogFragmentCompat through the parent/target Fragment) in the parent/target Fragment is not initialized. Maybe this helps to fix this issue.
ni...@google.com <ni...@google.com> #5
Ah, hmm. I've seen some (unrelated) issues internally with fragment ID recycling. Feels like kind of a misguided idea in general. I think a root fix to this lies in tweaking the fragment manager.
In the mean time, you can try to arrange your fragments such that fragments created earlier remain active (being on the backstack counts).
In the mean time, you can try to arrange your fragments such that fragments created earlier remain active (being on the backstack counts).
ch...@utildata.de <ch...@utildata.de> #6
Your workaround seems to work properly, even if infinite backstack growth isn't desirable.
A possible fix to this issue is to use available indices greater than the current fragments target fragment (if one is set) index only in the makeActive method of FragmentManagerImpl.
A possible fix to this issue is to use available indices greater than the current fragments target fragment (if one is set) index only in the makeActive method of FragmentManagerImpl.
dr...@gmail.com <dr...@gmail.com> #7
Any time table on fixing this?
I'm planning to release a first alpha of my app and this preferences UI is the last thing I'm working on...
I'm planning to release a first alpha of my app and this preferences UI is the last thing I'm working on...
dr...@gmail.com <dr...@gmail.com> #8
Another much cleaner and reasonable fix:
Use getChildFragmentManager() instead of getFragmentManager() in PreferenceFragmentCompat.onDisplayPreferenceDialog();
and use getParentFragment() instead of getTargetFragment() in PreferenceDialogFragmentCompat.
This way framework guarantees the order of calling onCreate(). It is also much more natural because preference dialog fragments are created and managed by our preference fragment.
Use getChildFragmentManager() instead of getFragmentManager() in PreferenceFragmentCompat.onDisplayPreferenceDialog();
and use getParentFragment() instead of getTargetFragment() in PreferenceDialogFragmentCompat.
This way framework guarantees the order of calling onCreate(). It is also much more natural because preference dialog fragments are created and managed by our preference fragment.
ni...@google.com <ni...@google.com> #9
Unfortunately moving the dialog to the child preference manager is incompatible with how the dialog is presented in the leanback UI. (in leanback, the dialog replaces the preference fragment that launched it)
dr...@gmail.com <dr...@gmail.com> #10
I've read the preference-leanback source.
In the leanback library, the creation and management of LeanbackPreferenceDialogFragment is handled by the parent LeanbackSettingsFragment, which puts the PreferenceFragmentCompat and LeanbackPreferenceDialogFragment onto the same backstack and calls setTargetFragment() for LeanbackPreferenceDialogFragment.
This is logical because they are to replace each other. And I also wonder in this case, will the backstack preserve the order of calling onCreate(), so it won't have the bug as perference-v7?
However with preference-v7, the PreferenceDialogFragment is created and managed by PreferenceFragmentCompat itself, *they are logically parent and children*, just as the LeanbackSettingsFragment with PreferenceFragmentCompat and LeanbackPreferenceDialogFragment which indeed called `getChildFragmentManager` for adding them.
So I think PreferenceFragmentCompat.onDisplayPreferenceDialog() should be implemented with `getChildFragmentManager`.
In the leanback library, the creation and management of LeanbackPreferenceDialogFragment is handled by the parent LeanbackSettingsFragment, which puts the PreferenceFragmentCompat and LeanbackPreferenceDialogFragment onto the same backstack and calls setTargetFragment() for LeanbackPreferenceDialogFragment.
This is logical because they are to replace each other. And I also wonder in this case, will the backstack preserve the order of calling onCreate(), so it won't have the bug as perference-v7?
However with preference-v7, the PreferenceDialogFragment is created and managed by PreferenceFragmentCompat itself, *they are logically parent and children*, just as the LeanbackSettingsFragment with PreferenceFragmentCompat and LeanbackPreferenceDialogFragment which indeed called `getChildFragmentManager` for adding them.
So I think PreferenceFragmentCompat.onDisplayPreferenceDialog() should be implemented with `getChildFragmentManager`.
dr...@gmail.com <dr...@gmail.com> #11
And by saying that the two implementation should be different because they are different in logic and behavior, I mean that I believe the EditTextPreference should have another implementation in preference-leanback, just as the TODO here: https://github.com/android/platform_frameworks_support/blob/master/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java#L77
ni...@google.com <ni...@google.com> #12
I'll probably be working around this by caching the needed fields the first time the fragment is created and storing them in the instance state. That way the fragment will be basically immune to re-creation order, and we'll be able to live with the fact that the preference object won't be available during fragment re-creation.
Description
EditTextPreference's dialog causes force close when it's open and the phone's orientation changes.
Stack trace:
[...]
Caused by: java.lang.NullPointerException
at android.support.v7.preference.PreferenceDialogFragmentCompat.onCreateDialog(PreferenceDialogFragmentCompat.java:66)
at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:308)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1026)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1207)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1189)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2001)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:165)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:507)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1231)
at android.app.Activity.performStart(Activity.java:5175)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2436)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4234)
at android.app.ActivityThread.access$700(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1372)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:5751)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1083)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:850)
at dalvik.system.NativeStart.main(Native Method)