Fixed
Status Update
Comments
il...@google.com <il...@google.com>
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #2
Hi Ed, Thank you so much for these suggestions. I've been reviewing them and merging them in. Hopefully it should be live. I've included a thank you note too in the article.
il...@google.com <il...@google.com> #3
Great! Thanks a lot, I'll look for the live updates soon!
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-master-dev
commit f1b1e806cd94d46c6b81520a963a36b15df97af0
Author: Ian Lake <ilake@google.com>
Date: Tue Apr 14 11:11:16 2020
Unwrap + safe cast the app context to Application
Since getApplicationContext() returns a Context and
not an Application, developers can use one or more
ContextWrappers to provide any number of layers of
interdirection between the Context returned and the
actual Application instance.
By calling getBaseContext() until we find an
Application instance and providing a fallback if
we never find one, we can ensure that we always
get a valid default factory.
Test: existing ViewModel tests still pass
BUG: 153762914
Change-Id: If9b6ecd25db2d8acebb4d1a72baae4b3510f5a7e
M fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
https://android-review.googlesource.com/1285826
Branch: androidx-master-dev
commit f1b1e806cd94d46c6b81520a963a36b15df97af0
Author: Ian Lake <ilake@google.com>
Date: Tue Apr 14 11:11:16 2020
Unwrap + safe cast the app context to Application
Since getApplicationContext() returns a Context and
not an Application, developers can use one or more
ContextWrappers to provide any number of layers of
interdirection between the Context returned and the
actual Application instance.
By calling getBaseContext() until we find an
Application instance and providing a fallback if
we never find one, we can ensure that we always
get a valid default factory.
Test: existing ViewModel tests still pass
BUG: 153762914
Change-Id: If9b6ecd25db2d8acebb4d1a72baae4b3510f5a7e
M fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
ap...@google.com <ap...@google.com> #5
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 937e2458359d689ae4f9ac18c1c303ed4e732bf0
Author: Ian Lake <ilake@google.com>
Date: Wed Apr 15 11:38:42 2020
Always support SavedStateHandle with the default factory
Now that SavedStateVieModelFactory supports a null
Application, we can support SavedStateHandle ViewModels
even when we cannot find an Application class.
Test: existing ViewModel tests still pass
BUG: 153762914
Change-Id: Idb9e64f2f1780b939dd31fa411324f3342bfcd12
M fragment/fragment-ktx/build.gradle
M fragment/fragment/build.gradle
M fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
https://android-review.googlesource.com/1285920
Branch: androidx-master-dev
commit 937e2458359d689ae4f9ac18c1c303ed4e732bf0
Author: Ian Lake <ilake@google.com>
Date: Wed Apr 15 11:38:42 2020
Always support SavedStateHandle with the default factory
Now that SavedStateVieModelFactory supports a null
Application, we can support SavedStateHandle ViewModels
even when we cannot find an Application class.
Test: existing ViewModel tests still pass
BUG: 153762914
Change-Id: Idb9e64f2f1780b939dd31fa411324f3342bfcd12
M fragment/fragment-ktx/build.gradle
M fragment/fragment/build.gradle
M fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
Description
Version used: 1.2.4
Devices/Android versions reproduced on: any
Fragment.getDefaultViewModelProviderFactory() makes a call to requireActivity() in order to obtain an instance of Application. This will fail if the Fragment is hosted in a FragmentHostCallback that doesn't reference an Activity (i.e. its context is not an Activity). getDefaultViewModelProviderFactory() and onCreateContextMenu() (which doesn't make sense for non-Activity Fragments) are the only places requireActivity() is used. Everywhere else uses get/requireContext() or allows getActivity() to return null.
Because Fragments are so prevalent, this makes the entire HasDefaultViewModelProviderFactory interface untrustworthy in codebases that may have non-Activity Fragments.
A simple fix would be to return a NewInstanceFactory() if mFragmentManager is non-null but getActivity() is null. This wouldn't support AndroidViewModels, but other ViewModels would still be able to be instantiated. Expanding SavedStateViewModelFactory to not require an Application would also help since the SavedStateHandler infrastructure doesn't appear to require the Application for anything else. Ideally, the Application would be able to be obtained elsewhere for non-Activity Fragments, but not supporting AndroidViewModels would be an acceptable trade off if that's not possible.
A less ideal solution would be to add another constructor to AndroidViewModels that takes a Context for use when an Application is not available, but that would clutter the API and is probably not worth it.