Infeasible
Status Update
Comments
st...@gmail.com <st...@gmail.com> #2
After looking more into this issue, ViewModels are persisted using retained fragments. After adding retained fragments to the sample app, we can observe that retained fragments are not able to survive landscape lock and unlock scenario either.
mo...@gmail.com <mo...@gmail.com> #3
Hey, currently I can't reproduce your issue.
Link you provided doesn't work, in my simple test project I don't observe described issue.
Could you please say reupload your project somewhere else?
Could you please say what kind of lockscreen, do you use? (it may effect issue)
Could you reproduce this behavior on other devices?
Link you provided doesn't work, in my simple test project I don't observe described issue.
Could you please say reupload your project somewhere else?
Could you please say what kind of lockscreen, do you use? (it may effect issue)
Could you reproduce this behavior on other devices?
st...@gmail.com <st...@gmail.com> #4
Hey,
Sorry about the repo link, here is the public one:https://github.com/karmazindmitriy/viewmodelscoping , git@github.com:karmazindmitriy/viewmodelscoping.git
Tested on:
1. Device: NEXUS 5X, API level: 24, lock method: PIN / PATTERN / SWIPE / PASSWORD. Can reproduce by unlocking with any of the unlocking methods. Can also reproduce by unlocking with fingerprint.
2. Device: NEXUS 5X, API level: 27, lock method: PIN / PATTERN / PASSWORD . Can reproduce only when unlocking the device with a fingerprint. Unlocking with PIN / PATTERN / PASSWORD works fine.
3. Device: Pixel, API level: 27, lock method: PIN (haven't tested other) + fingerprint. Can reproduce only when unlocking the device with a fingerprint. Unlocking with PIN / PATTERN / PASSWORD works fine.
Hope this is helpful, please let me know if you need any other info.
Sorry about the repo link, here is the public one:
Tested on:
1. Device: NEXUS 5X, API level: 24, lock method: PIN / PATTERN / SWIPE / PASSWORD. Can reproduce by unlocking with any of the unlocking methods. Can also reproduce by unlocking with fingerprint.
2. Device: NEXUS 5X, API level: 27, lock method: PIN / PATTERN / PASSWORD . Can reproduce only when unlocking the device with a fingerprint. Unlocking with PIN / PATTERN / PASSWORD works fine.
3. Device: Pixel, API level: 27, lock method: PIN (haven't tested other) + fingerprint. Can reproduce only when unlocking the device with a fingerprint. Unlocking with PIN / PATTERN / PASSWORD works fine.
Hope this is helpful, please let me know if you need any other info.
mo...@gmail.com <mo...@gmail.com> #5
Thanks, yep, I was able to reproduce it.
st...@gmail.com <st...@gmail.com> #6
Oh, another instance when platform doesn't call onSaveInstanceState, but calls onStop and onRetainNonConfiguration, so fragments are confused, we are going to fix fragments so they work around this behavior.
ir...@gmail.com <ir...@gmail.com> #7
Are you referring to the first `onStop` that happens right after unlock (line 12 in screenshot)?
sk...@gmail.com <sk...@gmail.com> #8
yep
dd...@gmail.com <dd...@gmail.com> #9
Hello, I Have notice the same issue when using ViewModel, here is the scenario:
1) open ActivityA
-gets ViewModel with reference: TestViewModel@e71fab8
2) rotate device
-gets ViewModel with reference: TestViewModel@e71fab8
3) open ActivityB
4) rotate device
5) press back (finish Activity B)
6) Activity A comes back from stack
-gets ViewModel with reference: TestViewModel@260072e
I have tested with two kinds of ViewModel, with factory and default creation method:
ViewModelProviders.of(this).get(TestViewModel::class.java)
ViewModelProviders.of(this, factory).get(DashboardViewModel::class.java)
Both Activities extends AppCompatActivity class.
I have made some research and find case when this issue do not happend:
1) open ActivityA (vertical)
-gets ViewModel with reference: TestViewModel@e71fab8
2) rotate device (horizontal)
-gets ViewModel with reference: TestViewModel@e71fab8
3) open ActivityB (horizontal)
4) rotate device (vertical)
5) rotate device (horizontal)
6) press back (finish Activity B)
7) Activity A comes back from stack (horizontal)
-gets ViewModel with reference: TestViewModel@e71fab8
So when I rotate device twice on Activity B and press back the Activity A do not recreate ViewModel, mayeby it is becouse it has the same orientation as befor putting it in activities stack.
1) open ActivityA
-gets ViewModel with reference: TestViewModel@e71fab8
2) rotate device
-gets ViewModel with reference: TestViewModel@e71fab8
3) open ActivityB
4) rotate device
5) press back (finish Activity B)
6) Activity A comes back from stack
-gets ViewModel with reference: TestViewModel@260072e
I have tested with two kinds of ViewModel, with factory and default creation method:
ViewModelProviders.of(this).get(TestViewModel::class.java)
ViewModelProviders.of(this, factory).get(DashboardViewModel::class.java)
Both Activities extends AppCompatActivity class.
I have made some research and find case when this issue do not happend:
1) open ActivityA (vertical)
-gets ViewModel with reference: TestViewModel@e71fab8
2) rotate device (horizontal)
-gets ViewModel with reference: TestViewModel@e71fab8
3) open ActivityB (horizontal)
4) rotate device (vertical)
5) rotate device (horizontal)
6) press back (finish Activity B)
7) Activity A comes back from stack (horizontal)
-gets ViewModel with reference: TestViewModel@e71fab8
So when I rotate device twice on Activity B and press back the Activity A do not recreate ViewModel, mayeby it is becouse it has the same orientation as befor putting it in activities stack.
gn...@gmail.com <gn...@gmail.com> #10
This behavior is due to FragmentActivity.onDestroy() calling into mViewModelStore.clear() if mRetaining is false. This is the case when the device is rotated and the affected activity is in the background (and probably in other conditions outlined above as well). It is not the case if the configuration changes when the activity is in the front.
Since the view model store has ben cleared, a new view model will be created for the affected activity after a configuration change in the background.
The behavior can be observed easily using a break point in ViewModelStore.clear()
Since the view model store has ben cleared, a new view model will be created for the affected activity after a configuration change in the background.
The behavior can be observed easily using a break point in ViewModelStore.clear()
ro...@gmail.com <ro...@gmail.com> #11
Easy way to detect the condition from within onDestroy() on your own activity:
override fun onDestroy() {
val current = ViewModelProviders.of(this).get(VM::class.java)
super.onDestroy()
val fresh = ViewModelProviders.of(this).get(VM::class.java)
if (current != fresh) {
Log.e("Main", "View model has been destroyed")
}
}
override fun onDestroy() {
val current = ViewModelProviders.of(this).get(VM::class.java)
super.onDestroy()
val fresh = ViewModelProviders.of(this).get(VM::class.java)
if (current != fresh) {
Log.e("Main", "View model has been destroyed")
}
}
fo...@gmail.com <fo...@gmail.com> #12
And a dirty workaround:
override fun onDestroy() {
val current = ViewModelProviders.of(this).get(VM::class.java)
super.onDestroy()
@Suppress("UNCHECKED_CAST")
val fresh = ViewModelProviders.of(this, object : ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>) = current as T
}).get(VM::class.java)
if (current != fresh) {
Log.e("Main", "View model destroyed!")
}
}
override fun onDestroy() {
val current = ViewModelProviders.of(this).get(VM::class.java)
super.onDestroy()
@Suppress("UNCHECKED_CAST")
val fresh = ViewModelProviders.of(this, object : ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>) = current as T
}).get(VM::class.java)
if (current != fresh) {
Log.e("Main", "View model destroyed!")
}
}
fo...@gmail.com <fo...@gmail.com> #13
It's happening also after entering to multi-window mode
fp...@gtempaccount.com <fp...@gtempaccount.com> #14
Somebody put my issue https://issuetracker.google.com/issues/78095959 as a duplicate of this one. I would like to clarify, if this is really the case and if the issue that I reported will also be taken into account when fixing this issue.
Quote #6:
"Oh, another instance when platform doesn't call onSaveInstanceState, but calls onStop and onRetainNonConfiguration, so fragments are confused, we are going to fix fragments so they work around this behavior."
In the case which I presented, onSaveInstanceState IS called. But after that the activity is destroyed, so are the fragments. But ViewModel is not being cleared. There is a condition which skips clearing ViewModel after state is saved:
/**
* Called when the fragment is no longer in use. This is called
* after {@link #onStop()} and before {@link #onDetach()}.
*/
@CallSuper
public void onDestroy() {
mCalled = true;
// Use mStateSaved instead of isStateSaved() since we're past onStop()
if (mViewModelStore != null && !mHost.mFragmentManager.mStateSaved) {
mViewModelStore.clear();
}
}
But for fragments that are destroyed, loaders must be reset, like it happens in case of activity. I think the right condition for loader lifecycle to work correctly should be something like this:
if (mViewModelStore != null) {
// Do not reset loaders on activity rotation
final Activity activity = getActivity();
if (activity != null && !activity.isChangingConfigurations()) {
fragment.mViewModelStore.clear();
}
}
So loaders are always reset in Fragment.onDestroy(), unless the activity is rotated. I think this is also applicable to ViewModel.
Quote #6:
"Oh, another instance when platform doesn't call onSaveInstanceState, but calls onStop and onRetainNonConfiguration, so fragments are confused, we are going to fix fragments so they work around this behavior."
In the case which I presented, onSaveInstanceState IS called. But after that the activity is destroyed, so are the fragments. But ViewModel is not being cleared. There is a condition which skips clearing ViewModel after state is saved:
/**
* Called when the fragment is no longer in use. This is called
* after {@link #onStop()} and before {@link #onDetach()}.
*/
@CallSuper
public void onDestroy() {
mCalled = true;
// Use mStateSaved instead of isStateSaved() since we're past onStop()
if (mViewModelStore != null && !mHost.mFragmentManager.mStateSaved) {
mViewModelStore.clear();
}
}
But for fragments that are destroyed, loaders must be reset, like it happens in case of activity. I think the right condition for loader lifecycle to work correctly should be something like this:
if (mViewModelStore != null) {
// Do not reset loaders on activity rotation
final Activity activity = getActivity();
if (activity != null && !activity.isChangingConfigurations()) {
fragment.mViewModelStore.clear();
}
}
So loaders are always reset in Fragment.onDestroy(), unless the activity is rotated. I think this is also applicable to ViewModel.
fp...@gtempaccount.com <fp...@gtempaccount.com> #15
Was about to report this issue. I too am observing the same issue - exactly as do...@gmail.com https://issuetracker.google.com/issues/73644080#comment9 describes it. I also noted that if the ViewModel is instantiated with a Fragment - ie: mViewModel = ViewModelProviders.of(<Fragment>).get(TestViewModel.class); - the ViewModel will always get the same instance back - even in the above described scenarios.
I found a sample project on GitHub where the issue is easily reproduced as well:https://github.com/jshvarts/SimpleViewModel
I found a sample project on GitHub where the issue is easily reproduced as well:
la...@gmail.com <la...@gmail.com> #16
- I have a temporary solution that we have implemented using retained fragments to hold the ViewModel.
See:https://bitbucket.org/sajeevmadu/viewmodeltest for the solution.
See:https://issuetracker.google.com/issues/78788599
for a video of the issue.
See:
See:
for a video of the issue.
br...@gmail.com <br...@gmail.com> #17
This is fixed internally and will be available in future releases of the fragment dependency.
ch...@gmail.com <ch...@gmail.com> #18
when and which version will this fix be included?
[Deleted User] <[Deleted User]> #19
The fix is available in 28.0.0-alpha3 and AndroidX 1.0.0-alpha3
gn...@gmail.com <gn...@gmail.com> #22
For anyone still following this thread: tried with 28.0.0-alpha3 and AndroidX 1.0.0-alpha3 and it doesn't happen anymore.
en...@gmail.com <en...@gmail.com> #23
Sadly moving to AndroidX is a huge issue for large projects. It makes so many build errors. I hope it gets fixed in future version of Android Studio
[Deleted User] <[Deleted User]> #24
If you're comfortable with alpha releases of the support library, you can raise your target to 28 and use 28.0.0-alpha3.
th...@gmail.com <th...@gmail.com> #25
Raising targetSdk is not needed. Only compileSdk needs to be raised to be able to use support lib 28
ma...@gmail.com <ma...@gmail.com> #26
Right, sorry about that. Realized this soon after but couldn’t edit the response :(
qw...@gmail.com <qw...@gmail.com> #27
This issue is not fixed in 2.0.0-rc01. How can you consider calling this version release candidate with this bug!
jo...@gmail.com <jo...@gmail.com> #28
Supportlib 28 and AndroidX 2.0.0-rc01 releases are not related to navigation - navigation/workmanager are still in alpha in a separate release process. They have yet to release an androidx-package version, so they aren't included included in the initial 2.0 arch components release process. See https://developer.android.com/topic/libraries/architecture/adding-components#navigation - you need to update your navigation library version specifically.
sa...@gmail.com <sa...@gmail.com> #29
I faced the same issue after calling startActivityForResult and rotate screen and then return the resulting intent. I noticed that this also caused the onCleared() of the ViewModel to be invoked in the calling activity's viewmodel.
jb...@android.com <jb...@android.com> #30
Re #29, if you're still having an issue with 28.0.0-alpha3 or higher (or 1.0.0-alpha2 in AndroidX), please file a new issue with a sample project that reproduces your issue.
jb...@android.com <jb...@android.com> #31
Can anyone please make a sample project to test it out, and say what are the steps?
I think the issue was fixed, at least for loaders.
I think the issue was fixed, at least for loaders.
li...@gmail.com <li...@gmail.com> #32
"Retained fragments to hold the ViewModel" is not a reliable solution. After reverted some requested runtime permissions, such as Storage, Location and so on, retained ViewModel will be changed to a fresh one!
na...@gmail.com <na...@gmail.com> #33
I'm getting a similar issue. Multiple instances on my view model are being created on screen rotate. Here's a link to my repo: https://github.com/rahulchowdhury/elly/tree/add-elephant-profile
gd...@gmail.com <gd...@gmail.com> #34
Re #33 - you're unconditionally adding a new Fragment in your MainActivity, meaning you're adding a new instance for every rotation. You need to surround that code with if (savedInstanceState == null).
af...@gmail.com <af...@gmail.com> #35
Whoops. Totally missed that one out. Sorry. 😅
[Deleted User] <[Deleted User]> #36
@34 @35 Or check if the fragment exists, using findfragmentbytag .
[Deleted User] <[Deleted User]> #37
I m a ex husband from engineering team of ooredoo myanmar telecomm company.We already seperated by legally.Last time i used her free sim , glaxy tab 2 (error/ no reason) and her z1 sony mobile amd also used her gmail/out look.I don't know what happened,but i only contact her and who is her friends to know to their local. Because i love her so and was so angry.I can say that.
[Deleted User] <[Deleted User]> #38
My ex wife,She is a engineer at optimization team. The team leader is a vietnamese.She has many friends of specialist of communication.But i don't understand what are they doing like that.
zk...@gmail.com <zk...@gmail.com> #39
hallo
Description
It appears that all Droid 2 devices share the same DeviceID 9774d56d682e549c
This breaks apps that use DeviceID as a test for trial versions... or a test for device uniqueness...