@Override publicvoidhandleResumeActivity(ActivityClientRecord r, boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus, String reason) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration // skip below steps for double-resume and r.mFinish = true case. if (!performResumeActivity(r, finalStateRequest, reason)) { return; } ... // 重点 if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); Viewdecor= r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManagerwm= a.getWindowManager(); WindowManager.LayoutParamsl= r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (r.mPreserveWindow) { a.mWindowAdded = true; r.mPreserveWindow = false; // Normally the ViewRoot sets up callbacks with the Activity // in addView->ViewRootImpl#setView. If we are instead reusing // the decor view we have to notify the view root that the // callbacks may have changed. ViewRootImplimpl= decor.getViewRootImpl(); if (impl != null) { impl.notifyChildRebuilt(); } } if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true; wm.addView(decor, l); // 这里调用了WindowManager的addView()方法 } else { // The activity will get a callback for this {@link LayoutParams} change // earlier. However, at that time the decor will not be set (this is set // in this method), so no action will be taken. This call ensures the // callback occurs with the decor set. a.onWindowAttributesChanged(l); } } } ... }
// do this last because it fires off messages to start doing things try { root.setView(view, wparams, panelParentView, userId);// 2 } catch (RuntimeException e) { finalintviewIndex= (index >= 0) ? index : (mViews.size() - 1); // BadTokenException or InvalidDisplayException, clean up. if (viewIndex >= 0) { removeViewLocked(viewIndex, true); } throw e; } } }
switch (specMode) { case MeasureSpec.UNSPECIFIED: result = size; break; case MeasureSpec.AT_MOST: case MeasureSpec.EXACTLY: result = specSize; break; } return result; }
publicstaticintgetChildMeasureSpec(int spec, int padding, int childDimension) { intspecMode= MeasureSpec.getMode(spec); intspecSize= MeasureSpec.getSize(spec);
intsize= Math.max(0, specSize - padding);
intresultSize=0; intresultMode=0;
switch (specMode) { // Parent has imposed an exact size on us case MeasureSpec.EXACTLY: if (childDimension >= 0) { resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } elseif (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size. So be it. resultSize = size; resultMode = MeasureSpec.EXACTLY; } elseif (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size. It can't be // bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } break;
// Parent has imposed a maximum size on us case MeasureSpec.AT_MOST: if (childDimension >= 0) { // Child wants a specific size... so be it resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } elseif (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size, but our size is not fixed. // Constrain child to not be bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } elseif (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size. It can't be // bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } break;
// Parent asked to see how big we want to be case MeasureSpec.UNSPECIFIED: if (childDimension >= 0) { // Child wants a specific size... let them have it resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } elseif (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size... find out how big it should // be resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size; resultMode = MeasureSpec.UNSPECIFIED; } elseif (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size.... find out how // big it should be resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size; resultMode = MeasureSpec.UNSPECIFIED; } break; } //noinspection ResourceType return MeasureSpec.makeMeasureSpec(resultSize, resultMode); }
// See how tall everyone is. Also remember max width. for (inti=0; i < count; ++i) { finalViewchild= getVirtualChildAt(i); if (child == null) { mTotalLength += measureNullChild(i); continue; }
if (child.getVisibility() == View.GONE) { i += getChildrenSkipCount(child, i); continue; }
nonSkippedChildCount++; if (hasDividerBeforeChildAt(i)) { mTotalLength += mDividerHeight; }
if (useLargestChild) { largestChildHeight = Math.max(childHeight, largestChildHeight); } }
if ((baselineChildIndex >= 0) && (baselineChildIndex == i + 1)) { mBaselineChildTop = mTotalLength; }
if (i < baselineChildIndex && lp.weight > 0) { thrownewRuntimeException("A child of LinearLayout with index " + "less than mBaselineAlignedChildIndex has weight > 0, which " + "won't work. Either remove the weight, or don't set " + "mBaselineAlignedChildIndex."); }
finalint childHeight; if (mUseLargestChild && heightMode != MeasureSpec.EXACTLY) { childHeight = largestChildHeight; } elseif (lp.height == 0 && (!mAllowInconsistentMeasurement || heightMode == MeasureSpec.EXACTLY)) { // This child needs to be laid out from scratch using // only its share of excess space. childHeight = share; } else { // This child had some intrinsic height to which we // need to add its share of excess space. childHeight = child.getMeasuredHeight() + share; }
// Child may now not fit in vertical dimension. childState = combineMeasuredStates(childState, child.getMeasuredState() & (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT)); }
// Add in our padding mTotalLength += mPaddingTop + mPaddingBottom; // TODO: Should we recompute the heightSpec based on the new total length? } else { alternativeMaxWidth = Math.max(alternativeMaxWidth, weightedMaxWidth);
// We have no limit, so make all weighted views as tall as the largest child. // Children will have already been measured once. if (useLargestChild && heightMode != MeasureSpec.EXACTLY) { for (inti=0; i < count; i++) { finalViewchild= getVirtualChildAt(i); if (child == null || child.getVisibility() == View.GONE) { continue; }
final LinearLayout.LayoutParamslp= (LinearLayout.LayoutParams) child.getLayoutParams();
publicvoidlayout(int l, int t, int r, int b) { if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) { if (isTraversalTracingEnabled()) { Trace.beginSection(mTracingStrings.onMeasureBeforeLayout); } onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec); if (isTraversalTracingEnabled()) { Trace.endSection(); } mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; }
@Override protectedvoidonLayout(boolean changed, int l, int t, int r, int b) { if (mOrientation == VERTICAL) { layoutVertical(l, t, r, b); } else { layoutHorizontal(l, t, r, b); } }