From 35e2ea02035e8b7eb7de5d7a1d51bf030dcb5b76 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Tue, 22 Mar 2016 10:40:29 -0700 Subject: Only call Drawable.setVisible(false) for visible outgoing drawables In framework views where we're handling the new visibility aggregated call we only update the drawable visibility when we're attached to a window. For old outgoing drawables being replaced, gate this on whether the drawable is already marked visible instead. This catches a case where views being inflated might set drawables in in a superclass constructor and have them replaced in a later constructor. Gating the call into a drawable that might invoke its callback (the view being constructed) avoids potential problems where overridden methods are called unexpectedly on a view subclass that has not finished running its constructor. This is a better check than isAttachedToWindow, as isAttachedToWindow will return false if the view has been temporarily detached from its parent by a view-recycling container. In those cases, the view would not correctly update the outgoing drawable. Bug 27461617 Change-Id: I733a2dd3e3df0a8d80d5dc542ca7b30064159d5d --- core/java/android/widget/ImageView.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'core/java/android/widget/ImageView.java') diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index 222a040d2b3c..02065779ef91 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -911,11 +911,17 @@ public class ImageView extends View { } if (mDrawable != null) { - mDrawable.setCallback(null); - unscheduleDrawable(mDrawable); - if (isAttachedToWindow()) { + // It's possible for this method to be invoked from the constructor before + // subclass constructors have run. Drawables can and should trigger invalidations + // and other activity with their callback on visibility changes, which shouldn't + // happen before subclass constructors finish. However, we won't have set the + // drawable as visible until the view becomes attached. This guard below keeps + // multiple calls to this method from constructors from causing issues. + if (mDrawable.isVisible()) { mDrawable.setVisible(false, false); } + mDrawable.setCallback(null); + unscheduleDrawable(mDrawable); } mDrawable = d; -- cgit v1.2.3