android 13 WMS/AMS系统开发 |
您所在的位置:网站首页 › erp与wms对接 › android 13 WMS/AMS系统开发 |
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {
//ignore
//根据client找到对应的WindowState
final WindowState win = windowForClientLocked(session, client, false);
//ignore
// Create surfaceControl before surface placement otherwise layout will be skipped
// (because WS.isGoneForLayout() is true when there is no surface.
if (shouldRelayout) {
try {
//创建对应的window需要的SurfaceControl,传递回应用,应用用他进行绘制
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
} catch (Exception e) {
//ignore
}
}
//调用最核心的performSurfacePlacement进行相关的layout操作
// We may be deferring layout passes at the moment, but since the client is interested
// in the new out values right now we need to force a layout.
mWindowPlacerLocked.performSurfacePlacement(true /* force */);
//ignore
if (!win.isGoneForLayout()) {
win.mResizedWhileGone = false;
}
//把相关config数据填回去
win.fillClientWindowFramesAndConfiguration(outFrames, mergedConfiguration,
false /* useLatestConfig */, shouldRelayout);
//把相关inset数据设置回去
outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());
//ignore
getInsetsSourceControls(win, outActiveControls);
}
Binder.restoreCallingIdentity(origId);
return result;
}
主要就有2个最关键步骤: 1、创建对应Window的SurfaceControl 2、计算出对应的window区域等,把inset和config传递回去 更多内容qqun:422901085 https://ke.qq.com/course/5992266#term_id=106217431 1、创建对应Window的SurfaceControl,这个之前图层结构树部分有讲解调用是createSurfaceControl: private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; } WindowSurfaceController surfaceController; try { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl"); surfaceController = winAnimator.createSurfaceLocked(); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } if (surfaceController != null) { surfaceController.getSurfaceControl(outSurfaceControl); ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win); outSurfaceControl.release(); } return result; }这里首先又调用到了winAnimator.createSurfaceLocked(); WindowSurfaceController createSurfaceLocked() { //ignore mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format, flags, this, attrs.type); //ignore }调用到了WindowSurfaceController构造: WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator, int windowType) { mAnimator = animator; title = name; mService = animator.mService; final WindowState win = animator.mWin; mWindowType = windowType; mWindowSession = win.mSession; Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl"); final SurfaceControl.Builder b = win.makeSurface() .setParent(win.getSurfaceControl()) .setName(name) .setFormat(format) .setFlags(flags) .setMetadata(METADATA_WINDOW_TYPE, windowType) .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid) .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid) .setCallsite("WindowSurfaceController");//此时其实还是属于Container,因为DisplayerContent创建 final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0); if (useBLAST) { b.setBLASTLayer();//非常关键,变成非Container } mSurfaceControl = b.build(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } 2、计算出对应的window区域等,把inset和config传递回去这个部分最关键方法就是 mWindowPlacerLocked.performSurfacePlacement(true /* force */); 下面来对他进行详细分析: final void performSurfacePlacement(boolean force) { 119 if (mDeferDepth > 0 && !force) { 120 mDeferredRequests++; 121 return; 122 } 123 int loopCount = 6; 124 do { 125 mTraversalScheduled = false; 126 performSurfacePlacementLoop();//调用performSurfacePlacementLoop 127 mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement); 128 loopCount--; 129 } while (mTraversalScheduled && loopCount > 0); 130 mService.mRoot.mWallpaperActionPending = false; 131 }performSurfacePlacementLoop private void performSurfacePlacementLoop() { //ignore mService.mRoot.performSurfacePlacement(); //ignore }这里会调用到RootWindowContainer的performSurfacePlacement void performSurfacePlacement() { 782 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement"); 783 try { 784 performSurfacePlacementNoTrace(); 785 } finally { 786 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 787 } 788 }接下来又到performSurfacePlacementNoTrace,接下来又会调用到最关键的applySurfaceChangesTransaction方法: private void applySurfaceChangesTransaction() { //ignore final int count = mChildren.size(); for (int j = 0; j //执行布局相关 // Perform a layout, if needed. performLayout(true /* initial */, false /* updateInputWindows */); pendingLayoutChanges = 0; //判断布局策略 mDisplayPolicy.beginPostLayoutPolicyLw(); forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); // Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges"); try { //挨个迭代每个窗口执行mApplySurfaceChangesTransaction forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } //做绘制前最后一些处理 prepareSurfaces(); //ignore }这里我们这次重点是performLayout,其他后面几篇blog再讲解 void performLayout(boolean initial, boolean updateInputWindows) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performLayout"); try { performLayoutNoTrace(initial, updateInputWindows); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } } private void performLayoutNoTrace(boolean initial, boolean updateInputWindows) { if (!isLayoutNeeded()) { return; } clearLayoutNeeded(); if (DEBUG_LAYOUT) { Slog.v(TAG, "-------------------------------------"); Slog.v(TAG, "performLayout: dw=" + mDisplayInfo.logicalWidth + " dh=" + mDisplayInfo.logicalHeight); } int seq = mLayoutSeq + 1; if (seq //ignore getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames); //ignore };调用是DisplayPolicy.java的layoutWindowLw public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) { //ignore mWindowLayout.computeFrames(attrs, win.getInsetsState(), displayFrames.mDisplayCutoutSafe, win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight, win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale, sTmpClientFrames); win.setFrames(sTmpClientFrames, win.mRequestedWidth, win.mRequestedHeight); }这里调用是WindowLayout.computeFrames 具体computeFrames的计算代码较长,主要就是会根据系统的inset情况来决定,比如statusbar,和navigationbar等,然后给app一个合适的frame |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |