From ce418e661ab52a08a2a2c3b2f10a4dd9adf33305 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 1 Mar 2011 14:31:38 -0800 Subject: Fix issue #3495749: Crash on choosing to open the downloaded images This is due to the window doing a relayout after its activity is stopped, at which point it may need to interact with the adapter to load data. The fix here is to tell ViewRoot about an activity being stopped and, if in this state, hold off on doing any new measurements and layouts of the hierarchy until it is no longer stopped. In this case the relayout was happening due to the cursor being deactivated, with causes the adapter to invalidate its data. Because this is now in a dialog window, this allows the window to actually be resized smaller (unlike when in a full screen activity), and boom. Change-Id: I26442b4679819b4a4e6bc56289afd3445526750b --- core/java/android/view/ViewRoot.java | 103 ++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 44 deletions(-) (limited to 'core/java/android/view/ViewRoot.java') diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index c7b19555716c..965c959f2db4 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -155,6 +155,10 @@ public final class ViewRoot extends Handler implements ViewParent, int mViewVisibility; boolean mAppVisible = true; + // Set to true if the owner of this window is in the stopped state, + // so the window should no longer be active. + boolean mStopped = false; + SurfaceHolder.Callback2 mSurfaceHolderCallback; BaseSurfaceHolder mSurfaceHolder; boolean mIsCreating; @@ -618,6 +622,15 @@ public final class ViewRoot extends Handler implements ViewParent, scheduleTraversals(); } + void setStopped(boolean stopped) { + if (mStopped != stopped) { + mStopped = stopped; + if (!stopped) { + scheduleTraversals(); + } + } + } + public ViewParent getParent() { return null; } @@ -760,7 +773,7 @@ public final class ViewRoot extends Handler implements ViewParent, boolean insetsChanged = false; - if (mLayoutRequested) { + if (mLayoutRequested && !mStopped) { // Execute enqueued actions on every layout in case a view that was detached // enqueued an action after being detached getRunQueue().executeActions(attachInfo.mHandler); @@ -1143,54 +1156,56 @@ public final class ViewRoot extends Handler implements ViewParent, mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight); } - boolean focusChangedDueToTouchMode = ensureTouchModeLocally( - (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0); - if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() - || mHeight != host.getMeasuredHeight() || contentInsetsChanged) { - childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); - childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); - - if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth=" - + mWidth + " measuredWidth=" + host.getMeasuredWidth() - + " mHeight=" + mHeight - + " measuredHeight=" + host.getMeasuredHeight() - + " coveredInsetsChanged=" + contentInsetsChanged); - - // Ask host how big it wants to be - host.measure(childWidthMeasureSpec, childHeightMeasureSpec); - - // Implementation of weights from WindowManager.LayoutParams - // We just grow the dimensions as needed and re-measure if - // needs be - int width = host.getMeasuredWidth(); - int height = host.getMeasuredHeight(); - boolean measureAgain = false; - - if (lp.horizontalWeight > 0.0f) { - width += (int) ((mWidth - width) * lp.horizontalWeight); - childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, - MeasureSpec.EXACTLY); - measureAgain = true; - } - if (lp.verticalWeight > 0.0f) { - height += (int) ((mHeight - height) * lp.verticalWeight); - childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, - MeasureSpec.EXACTLY); - measureAgain = true; - } - - if (measureAgain) { - if (DEBUG_LAYOUT) Log.v(TAG, - "And hey let's measure once more: width=" + width - + " height=" + height); + if (!mStopped) { + boolean focusChangedDueToTouchMode = ensureTouchModeLocally( + (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0); + if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() + || mHeight != host.getMeasuredHeight() || contentInsetsChanged) { + childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); + childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); + + if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth=" + + mWidth + " measuredWidth=" + host.getMeasuredWidth() + + " mHeight=" + mHeight + + " measuredHeight=" + host.getMeasuredHeight() + + " coveredInsetsChanged=" + contentInsetsChanged); + + // Ask host how big it wants to be host.measure(childWidthMeasureSpec, childHeightMeasureSpec); + + // Implementation of weights from WindowManager.LayoutParams + // We just grow the dimensions as needed and re-measure if + // needs be + int width = host.getMeasuredWidth(); + int height = host.getMeasuredHeight(); + boolean measureAgain = false; + + if (lp.horizontalWeight > 0.0f) { + width += (int) ((mWidth - width) * lp.horizontalWeight); + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, + MeasureSpec.EXACTLY); + measureAgain = true; + } + if (lp.verticalWeight > 0.0f) { + height += (int) ((mHeight - height) * lp.verticalWeight); + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, + MeasureSpec.EXACTLY); + measureAgain = true; + } + + if (measureAgain) { + if (DEBUG_LAYOUT) Log.v(TAG, + "And hey let's measure once more: width=" + width + + " height=" + height); + host.measure(childWidthMeasureSpec, childHeightMeasureSpec); + } + + mLayoutRequested = true; } - - mLayoutRequested = true; } } - final boolean didLayout = mLayoutRequested; + final boolean didLayout = mLayoutRequested && !mStopped; boolean triggerGlobalLayoutListener = didLayout || attachInfo.mRecomputeGlobalAttributes; if (didLayout) { -- cgit v1.2.3