Status Update
Comments
ri...@google.com <ri...@google.com> #2
<item type="id" name="metricsStateHolder"/>
<item type="id" name="metricsDelegator"/>
These are assigned unique values at build time. As long as they are only ever used to assign objects of the correct type with those tags, there shouldn't be the kind of classCast exception seen above, and the assignments look correct, eg:
metricsStateHolder = Holder()
rootView.setTag(R.id.metricsStateHolder, metricsStateHolder)
and
delegator = DelegatingFrameMetricsListener(delegates)
decorView.setTag(R.id.metricsDelegator, delegator)
Logging shows ids are indeed unique and off by one, eg:
2131230959, 2131230958
Still investigating
ri...@google.com <ri...@google.com> #3
We synchronize access to some structures in JankStats already for other potential race conditions; we should be able to similarly protect access to the tags array for use between threads.
ri...@google.com <ri...@google.com> #4
There are various other calls to getTag/setTag that have been modified to ensure they are called from the UI thread, so things should be more solid (in an upcoming fix).
di...@gmail.com <di...@gmail.com> #5
According to datadog a user clicked a deeplink that navigates into our app.
java.lang.ClassCastException: com.xxx.ui.main.MainActivity cannot be cast to androidx.metrics.performance.PerformanceMetricsState$Holder
at androidx.metrics.performance.PerformanceMetricsState$Companion.getHolderForHierarchy(Unknown Source:27)
at androidx.metrics.performance.a.onFrameMetricsAvailable(Unknown Source:162)
at android.view.FrameMetricsObserver.onFrameMetricsAvailable(FrameMetricsObserver.java:59)
at android.graphics.HardwareRendererObserver.lambda$notifyDataAvailable$0$HardwareRendererObserver(HardwareRendererObserver.java:93)
at android.graphics.HardwareRendererObserver$$ExternalSyntheticLambda0.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:980)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loopOnce(Looper.java:238)
at android.os.Looper.loop(Looper.java:357)
at android.os.HandlerThread.run(HandlerThread.java:85)
ni...@parshipgroup.com <ni...@parshipgroup.com> #6
Is there any update on this issue? I can see pending code changes linked to this bug, but they are not yet merged (seems like CR is hanging without any action for a few months already).
ek...@uber.com <ek...@uber.com> #7
Project: platform/frameworks/support
Branch: androidx-main
Author: Chet Haase <
Link:
Make use of View tags thread-safe, and simplify delegate scheduling
Expand for full commit details
Make use of View tags thread-safe, and simplify delegate scheduling
We stash a single library-wide instance of our pre draw listener on
the DecorView on lower API levels. This could previously happen from a
couple of different threads, and View tags are not thread safe, which
can cause potential race condition errors if the underlying tag
storage is accessed in parallel from different threads.
This fix posts any changes to both the onPreDrawListener and the tags
to happen from the main thread to make them safe.
This also removes unnecessary logic from the onPreDraw loop itself,
since delegates cannot be scheduled for addition or removal during the
loop due to the synchronized block.
This fix also simplifies logic of singleFrameState removal (it now
happens while processing frames directly, on the following frame),
which gets rid of the need to synchronously get and use the state
holder from the FrameMetrics thread.
Bug: 311218678
Test: Manual testing to verify correct threading behavior, JankStatsTests passes
Relnote: Fix crashes `DelegatingFrameMetricsListener cannot be cast...`
Change-Id: Id891c0cfdd7f45ef9e3b068644a113f39c8fc383
Files:
- M
metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
- M
metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStats.kt
- M
metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt
- M
metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi24Impl.kt
- M
metrics/metrics-performance/src/main/java/androidx/metrics/performance/PerformanceMetricsState.kt
Hash: 68264e9d7d70b0af375d6cf4c27a3407657a5b80
Date: Mon Jan 08 17:23:46 2024
ek...@uber.com <ek...@uber.com> #8
I still see issues in the API24+ impl, reopening.
at...@netflix.com <at...@netflix.com> #9
Project: platform/frameworks/support
Branch: androidx-main
Author: Chris Craik <
Link:
Improve tag/listener update safety on API 24+
Expand for full commit details
Improve tag/listener update safety on API 24+
Improve JankStats API 24 impl to reduce thread hops and simplify
delegate iteration/adding/removal. This brings the API 24 impl to be
much closer to the API 16 implementation.
Also ensures that delegates and window frame metrics available
listeners are consistently set on main thread.
Test: JankStatsTest
Fixes: 311218678
Change-Id: I2ab7c892ae114708f3cd8e80f180ab73e32b9d11
Files:
- M
metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi24Impl.kt
Hash: f185f92ddcc005dfaa62ab4ed2816faabddc2288
Date: Wed Feb 26 15:03:31 2025
sa...@google.com <sa...@google.com> #10
Any ETA on the new release?
an...@google.com <an...@google.com> #11
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.metrics:metrics-performance:1.0.0-beta02
ek...@uber.com <ek...@uber.com> #12
ek...@uber.com <ek...@uber.com> #13
This fix was released yesterday with androidx.metrics:metrics-performance:1.0.0-beta02
, see
Please try it out and let us know if it doesn't address the problem.
an...@google.com <an...@google.com> #14
an...@google.com <an...@google.com>
do...@google.com <do...@google.com> #15
Just spoke with Andrew who informed me that the fix is well underway, and the hope is that it'll land within the next 6 weeks.
an...@google.com <an...@google.com> #16
Hey all, quick update here.
We've partially landed this fix. There's
In the short term: You will be able to receive this fix by upgrading to androidx.transition:transition:1.6.0-alpha01
when it is released (Probably in mid-December, but possibly in mid-January because of the upcoming US holidays). That will also upgrade androidx.core:core
to its latest version (which will probably be 1.16.0-alpha01
) and introduce a new dependency on androidx.core:core-viewtree:1.0.0-alpha01
, which is a new module we introduced as part of this change. You will not need to update any Compose dependencies to get the bug fix.
In the long term: We're planning to include a transitive dependency bump as part of the compose-ui 1.9.0 alphas. This bug will stay open until that happens. At some point, this will also work its way into a BOM, but I can't say when. We also can't include this in 1.8.0, unfortunately, because Compose is moving into beta soon, and beta libraries can't depend on core-viewtree
since it's in alpha currently.
ap...@google.com <ap...@google.com> #17
Project: platform/frameworks/support
Branch: androidx-main
Author: Andrew Bailey <
Link:
Set disjoint parents in transition overlays
Expand for full commit details
Set disjoint parents in transition overlays
Test: ComposeViewOverlayTest, in follow-up CL
Bug: b/340894487, b/287484338
Relnote: """
Transition now sets the disjoint parent for ViewOverlays used to
animate its transitions. This allows for the resolution of owners
through the disjoint parent, which means you can now correctly
resolve ViewModels, lifecycles, etc. during a transition.
"""
Change-Id: I10a16c84ba1efbf89a503418889ddd56bb711bed
Files:
- M
fragment/integration-tests/testapp/build.gradle
- M
navigation/integration-tests/testapp/build.gradle
- M
transition/transition-ktx/build.gradle
- M
transition/transition/build.gradle
- M
transition/transition/src/main/java/androidx/transition/GhostViewHolder.java
- M
transition/transition/src/main/java/androidx/transition/TransitionUtils.java
- M
transition/transition/src/main/java/androidx/transition/Visibility.java
Hash: b4846dbfd6e1e98421fe44d673965622fb5e66a4
Date: Wed Jul 31 09:56:27 2024
an...@google.com <an...@google.com> #18
androidx.transition:transition:1.6.0-alpha01
is included in today's androidx release. For everyone running into this issue, please upgrade your transition dependency to this version.
The next steps on our end are to bump the transition version that Compose UI depends on, which needs to wait until we bump the androidx-main branch to Compose 1.9.0-alpha01.
Bugjuggler: wait 2 months
bu...@google.com <bu...@google.com> #19
gb...@netflix.com <gb...@netflix.com> #20
bu...@google.com <bu...@google.com>
br...@target.com <br...@target.com> #21
FYI I'm still seeing this crash with Transition 1.6.0-alpha01.
Stacktrace:
java.lang.IllegalStateException: ViewTreeLifecycleOwner not found from android.view.ViewOverlay$OverlayViewGroup{2f4358c V.E...... ......ID 0,0-1080,2138}
at androidx.compose.ui.internal.InlineClassHelperKt.throwIllegalStateExceptionForNullCheck(InlineClassHelper.kt:30)
at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer(WindowRecomposer.android.kt:466)
at androidx.compose.ui.platform.WindowRecomposer_androidKt.createLifecycleAwareWindowRecomposer$default(WindowRecomposer.android.kt:327)
at androidx.compose.ui.platform.WindowRecomposerFactory$Companion.LifecycleAware$lambda$0(WindowRecomposer.android.kt:170)
at androidx.compose.ui.platform.WindowRecomposerFactory$Companion.$r8$lambda$FWAPLXs0qWMqekhMr83xkKattCY(Unknown Source:0)
at androidx.compose.ui.platform.WindowRecomposerFactory$Companion$$ExternalSyntheticLambda0.createRecomposer(D8$$SyntheticClass:0)
at androidx.compose.ui.platform.WindowRecomposerPolicy.createAndInstallWindowRecomposer$ui_release(WindowRecomposer.android.kt:226)
at androidx.compose.ui.platform.WindowRecomposer_androidKt.getWindowRecomposer(WindowRecomposer.android.kt:302)
at androidx.compose.ui.platform.AbstractComposeView.resolveParentCompositionContext(ComposeView.android.kt:251)
at androidx.compose.ui.platform.AbstractComposeView.ensureCompositionCreated(ComposeView.android.kt:258)
at androidx.compose.ui.platform.AbstractComposeView.onAttachedToWindow(ComposeView.android.kt:290)
at android.view.View.dispatchAttachedToWindow(View.java:21980)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3490)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.addViewInner(ViewGroup.java:5318)
at android.view.ViewGroup.addView(ViewGroup.java:5104)
at android.view.ViewGroup.addView(ViewGroup.java:5044)
at android.view.ViewGroup.addView(ViewGroup.java:5016)
at android.view.ViewOverlay$OverlayViewGroup.add(ViewOverlay.java:209)
at android.view.ViewGroupOverlay.add(ViewGroupOverlay.java:72)
at androidx.core.view.ViewCompat.addOverlayView(ViewCompat.java:2854)
at androidx.transition.TransitionUtils.createViewBitmap(TransitionUtils.java:103)
at androidx.transition.TransitionUtils.copyViewImage(TransitionUtils.java:64)
at androidx.transition.Visibility.onDisappear(Visibility.java:400)
at androidx.transition.Visibility.createAnimator(Visibility.java:254)
at androidx.transition.Transition.createAnimators(Transition.java:789)
at androidx.transition.TransitionSet.createAnimators(TransitionSet.java:458)
at androidx.transition.TransitionSet.createAnimators(TransitionSet.java:458)
at androidx.transition.Transition.playTransition(Transition.java:1912)
at androidx.transition.TransitionManager$MultiListener.onPreDraw(TransitionManager.java:301)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1176)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3772)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:882)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
br...@target.com <br...@target.com> #22
I was able to resolve the specific flavor of the crash described in #21 - the cause was a particular test screen that used android.R.id.content
as a Fragment container for transactions. Setting up that test Activity with an actual layout file with a FragmentContainerView
to host the Fragments resolved the crash.
Description
Jetpack Compose version: 1.4.3
Jetpack Compose component used: UI, ComposeView
Android Studio Build: Android Studio Hedgehog | 2023.1.1 Canary 8 Build #AI-231.9011.34.2311.10290408
Kotlin version: 1.8.10
Steps to Reproduce:
Visibility
Transition
in which the RecyclerView disappears.recyclerView.smoothScrollToPosition()
to reveal the off-screen ComposeView.Sample project attached. Click any item (without scrolling) to run.
I'm seeing this crash infrequently in a production app, and while we should probably avoid calling
smoothScrollToPosition()
on a view that we know is disappearing, this ideally wouldn't crash. Not sure if this is more an issue with RecyclerView or Compose.Stack trace: