Status Update
Comments
vi...@google.com <vi...@google.com>
[Deleted User] <[Deleted User]> #2
class FixDrawerLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) : DrawerLayout(context, attrs) {
fun registerToFragmentLifecycle(fragment: Fragment) {
fragment.viewLifecycleOwner.launchOnLifecycleDestroy {
super.onDetachedFromWindow()
}
}
}
sc...@gmail.com <sc...@gmail.com> #3
With markdown the same:
I have a project on SingleActivity. And in manifest android:enableOnBackInvokedCallback="true". I have a Root Fragment with a toolbar to which I attach a DrawerLayout.
<!-- XML Root Fragment -->
<androidx.drawerlayout.widget.DrawerLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.appbar.MaterialToolbar />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.core.widget.NestedScrollView
android:layout_gravity="start">
</androidx.drawerlayout.widget.DrawerLayout>
On button click in DrawerLayout I change RootFragment and lose all View in this Xml after onDestroyView. I don't call close() or closeDrawer() because I need the old state when I return to this fragment. But!
The DrawerLayout calls onDetachedFromWindow() which calls updateBackInvokedCallbackState() where ViewCompat.isAttachedToWindow(this) returns true and all the following condition is also true.
boolean shouldBeRegistered = visibleDrawer != null
&& currentDispatcher != null
&& getDrawerLockMode(visibleDrawer) == LOCK_MODE_UNLOCKED
&& ViewCompat.isAttachedToWindow(this);
As a consequence, the following code cannot be executed:
} else if (!shouldBeRegistered && mBackInvokedDispatcher != null) {
Api33Impl.tryUnregisterOnBackInvokedCallback(
mBackInvokedDispatcher, mBackInvokedCallback);
mBackInvokedDispatcher = null;
}
Where mBackInvokedDispatcher != null is true, and shouldBeRegistered is true (but !shouldBeRegistered is false).
Consequently, my mechanical back button or slide (back gesture) is blocked and not called on a new Root fragment when the DrawerLayout is Destroyed.
<!-- new Root fragment -->
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.appbar.MaterialToolbar />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
There may be a workaround, but that's not all. The fact is that LeakCanary reacts to this error, which claims that after registerOnBackInvokedCallback and not called tryUnregisterOnBackInvokedCallback, a memory leak occurs.
fast fix: android:enableOnBackInvokedCallback="false" or downgrade DrawerLayout to 1.1.1 or
[Deleted User] <[Deleted User]> #4
What I've seen is that when I show a new fragment as a result of a drawer layout navigation view being selected, back gestures break with `enableOnBackInvokedCallback` on stop working - and I saw the same else if block you mentioned above _not_ get called and result in stale/stuck back handlers consuming the gestures in this scenario.
I was able to delay showing the fragment until after the drawer layout closed, and the issue did not exist there.
The odd thing is - when I try out older drawer layout versions, the bug still exists. So maybe it's something deeper? I'm working to get a sample app setup to demo this, will circle back soon but wanted to add my current observations.
da...@loylap.com <da...@loylap.com> #5
after the drawer layout closed
According to my requirements, it should not close, since there is a screen animation where you can see that it is open. So the hot fix only helps through custom view.
fun registerToFragmentLifecycle(fragment: Fragment) {
fragment.viewLifecycleOwner.launchOnLifecycleDestroy {
super.onDetachedFromWindow()
}
}
da...@loylap.com <da...@loylap.com> #6
related to `launchOnLifecycleDestroy` - what is that method? I don't see it anywhere in my repo/online. Is that a custom API? Would be curious what that does!
sp...@google.com <sp...@google.com> #7
Here's my sample app btw -
Again, I'm not sure if our issues are exactly the same, but I get "stuck" not being able to swipe back between fragments after navigating to a fragment starting from a menu item being selected in a Drawer Layout - so it sounds similar...
aa...@google.com <aa...@google.com> #8
launchOnLifecycleDestroy ->
fun(block: suspend CoroutineScope.(Lifecycle.Event) -> Unit) {
coroutineScope.launch {
val observer = LifecycleEventObserver { _, event -> launch { if (Event.ON_DESTROY == event) block(event) } }
addObserver(observer)
try {
awaitCancellation()
} catch (_: CancellationException) {
removeObserver(observer)
}
}
}
da...@loylap.com <da...@loylap.com> #9
I found that if the drawer layout is part of a fragment, which is in turn replaced with another fragment as part of a navigation action, the bug occurs (back actions are consumed and not forwarded to the app as expected).
However, if you place the drawer layout as part of the parent activity, no bug occurs when you navigate from the drawer layout to another fragment/back/etc.
I assume that's because the drawer layout, when part of the activity, never goes destroyed/removed from the view, so it does not encounter the bug in question.
This is beginning to look like a separate issue related to navigation logic with drawer layouts in fragments/non-activity lifecycles.
ks...@atlassian.com <ks...@atlassian.com> #10
I agree with you completely.
da...@loylap.com <da...@loylap.com> #11
You download Flamingo or use adb my friend, they killed it by accident
[Deleted User] <[Deleted User]> #12
Or you can download older build like chipmunk or disable experimental logcat. But in dolhin it is not available with the new logcat.
kr...@gmail.com <kr...@gmail.com> #13
The missing info here is how to retrieve it in Flamingo. It's not called "Device Monitor", "Device File Explorer" doesn't exist as well.
What you look for is inside "Device Explorer" tab in bottom right, then there is a tab called "Processes" where you can Force stop or kill it.
is...@motorolasolutions.com <is...@motorolasolutions.com> #14
Looks like this tab is missing again in the latest flamingo
sp...@google.com <sp...@google.com> #15
The Device Monitor tool window is available in Studio Giraffe. Flamingo will not have it.
aa...@google.com <aa...@google.com> #16
Note that if having the Terminate Application
action is crucial for you, you can still disable the new Logcat tool window in EE and revert to the old tool window that has that action.
Settings -> Experimental
[Deleted User] <[Deleted User]> #17
sp...@google.com <sp...@google.com> #18
The Terminate Application
action is available in Studio Giraffe, where is it is part of Device Explorer
. In earlier Studio versions you may get it by switching to the old Logcat by unchecking Settings > Experimental > Enable new Logcat tool window.
ww...@gmail.com <ww...@gmail.com> #19
th...@gmail.com <th...@gmail.com> #20
+1
Description
Hi team,
the new Logcat is missing feature called 'Terminate Application'. Also asked here:https://stackoverflow.com/questions/73898589/where-has-the-terminate-application-button-gone-in-the-new-logcat-android-stu?newreg=b7965bfdc8a34f848795007f331197eb
We use it to kill the application in the background and than look if the all of our configuration, viewModels, etc was restored properly.
Can you please restore this feature?