-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getMvpDelegate().onDestroy() not called in MvpAppCompatFragment in some cases #95
Comments
Can you please specify reproduction steps a bit more clearly? I can't quite understand how exactly should I "remove all fragments and add another" to reproduce this issue. |
Seems I have similar issue, but with different flow. You just need to open activity for result and change fragments in onActivityResult when it's closed. Simple project to reproduce the issue: https://drive.google.com/file/d/1FXbj1F0norFwjzyMM-z8MaSkmkg20ZAU/view?usp=sharing |
For reproduce you need clear backstack in fragment manager, e.g.
Now i use this implementation (mixed with Mosby's solution) :
|
Thank you for clarification! I'll look at this issue soon. |
So yeah, it is definitely a problem. I kinda want to stop using those hacky solutions but it seems there is no official way to check if fragment is removing finally or temporary. I have another idea though. What if for every @xanderblinov @alaershov @aasitnikov @senneco what do you think about this approach? |
There kinda is a way, take a look at how the viewModelStore is implemented in JetPack ViewModel. There is a check, something like |
So it seems for me we have 3 options to fix this:
override fun onStart() {
super.onStart()
try {
val activeFragmentMethod = FragmentManager::class.java.getDeclaredMethod("getActiveFragments")
activeFragmentMethod.isAccessible = true
@Suppress("UNCHECKED_CAST")
val activeFragments = activeFragmentMethod.invoke(supportFragmentManager) as List<Fragment>
activeFragments.forEach {
(it as? MvpFragment)?.resetSavedStateFlag()
}
} catch (t: Throwable) {
Log.w(javaClass.simpleName, t)
}
} Obvious drawbacks are - already hacky solution became even more hacky, reflection usage (which is slow on Android), usage of private api which may change unpredictably and also increased difficulty to properly setup library for users when they are not using our base containers.
override fun onDestroy() {
super.onDestroy()
if (activity?.isFinishing == true) {
mvpDelegate.onDestroy()
return
}
if (activity?.isChangingConfigurations == true && isInBackStack) {
return
}
if (isRemoving) {
mvpDelegate.onDestroy()
return
}
val isAnyParentRemoving = generateSequence(parentFragment) { parentFragment }
.any { it.isRemoving }
if (isAnyParentRemoving) {
mvpDelegate.onDestroy()
}
}
private val isInBackStack: Boolean
get() {
return try {
val backStackNestingField = Fragment::class.java.getDeclaredField("mBackStackNesting")
backStackNestingField.isAccessible = true
val backStackNesting: Int = backStackNestingField.getInt(this)
backStackNesting > 0
} catch (t: Throwable) {
false
}
} Again, very hacky solution, usage of private api, reflection, but not that different from current one in terms of setup difficulty. Actually in this case we can get rid of
|
So we had some internal discussion about this issue and also I've done some research which led to creating new issue in androidx.fragment library. Basically android fragments using It seems to me that checking if fragment saves its state before |
Hi, I faced with similar issue when I use ViewPager2 with FragmentStateAdapter. When we leave screen with ViewPager inner presenters for fragments(pages) are not destroying. |
For reproducing
State 1. Activity -> FullScreenFragment1
Then run
State 2. Activity -> FullScreenFragment1 -> FullScreenFragment2
Collapse the app and restore it.
Then remove all fragments and add another.
As a result getMvpDelegate().onDestroy() will not be called for FullScreenFragment1
This is because onStart() not called for fragments in backstack and variable isStateSaved will be true.
Possible solution is the using activity.isChangingConfigurations() instead of isStateSaved
The text was updated successfully, but these errors were encountered: