96SEO 2026-02-19 06:54 0
1.获取WindowManager对象2.客户端添加view3.

讲解通过Activity添加窗口流程。
主要讲解整个WMS创建到绘制的流程
frameworks/base/core/java/android/app/Activity.javaframeworks/base/core/java/android/app/Activity.javaframeworks/base/core/java/android/app/ActivityThread.javaframeworks/base/core/java/android/app/ContextImpl.javaframeworks/base/core/java/android/view/WindowManagerImpl.javaframeworks/base/core/java/android/view/ViewRootImpl.javaframeworks/base/services/core/java/com/android/server/wm/WindowManagerService.javaframeworks/base/services/core/java/com/android/server/wm/Session.java
getSystemService(WINDOW_SERVICE);对应Activity实现方法判断了对应windowManger
super.getSystemService(name);}mWindowManager
lastNonConfigurationInstances,Configuration
{attachBaseContext(context);mWindow
并设置WindowManager到phoneWindow对应的变量mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken,
mComponent.flattenToString(),(info.flags
ActivityInfo.FLAG_HARDWARE_ACCELERATED)
{mWindow.setContainer(mParent.getWindow());}//
mWindow.getWindowManager();....}(WindowManager)context.getSystemService(Context.WINDOW_SERVICE)
performLaunchActivity(ActivityClientRecord
createBaseContextForActivity(r);Activity
{...activity.attach(appContext,
r.lastNonConfigurationInstances,
r.configCallback,r.assistToken,
r.shareableActivityToken);...}查看对应
SystemServiceRegistry》。
查看对应的实现的
SystemServiceRegistry.getSystemService(this,
name);}registerService(Context.WINDOW_SERVICE,
CachedServiceFetcherWindowManager()
WindowManagerImpl(ctx);}});2.客户端添加view
windowManager.addView(textView,
WindowManagerGlobal.getInstance();Overridepublic
{applyTokens(params);mGlobal.addView(view,
mParentWindow,mContext.getUserId());}global
获取该view是否已添加如果已添加但是处于移除中则执行doDie方法否则抛异常创建viewRootImpl并分别将参数放到
IllegalArgumentException(display
IllegalArgumentException(Params
WindowManager.LayoutParams);}final
{parentWindow.adjustLayoutParamsForSubWindow(wparams);}
(context.getApplicationInfo().flags
ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;}}//
{mRoots.get(i).loadSystemProperties();}}}};SystemProperties.addChangeCallback(mSystemPropertyUpdater);}//
queue.mRoots.get(index).doDie();}
WindowManager.LayoutParams.FIRST_SUB_WINDOW
WindowManager.LayoutParams.LAST_SUB_WINDOW)
(mRoots.get(i).mWindow.asBinder()
WindowManagerGlobal.getWindowSession()
ViewRootImpl(view.getContext(),
display);view.setLayoutParams(wparams);//
添加到对应的数组mViews.add(view);mRoots.add(root);mParams.add(wparams);//
ServiceManager.getService(“window”)
UnsupportedAppUsageInputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();IWindowManager
getWindowManagerService();sWindowSession
{ValueAnimator.setDurationScale(scale);}});}
e.rethrowFromSystemServer();}}return
sWindowSession;}}UnsupportedAppUsagepublic
IWindowManager.Stub.asInterface(ServiceManager.getService(window));try
{ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());sUseBLASTAdapter
sWindowManagerService.useBLAST();}}
e.rethrowFromSystemServer();}}return
sWindowManagerService;}}Overridepublic
openSession(IWindowSessionCallback
scheduleTraversals-doTraversal-performTraversals
客户端获取到WMS计算的窗口大小后进一步测量该窗口下View的宽度和高度
createSyncIfNeeded-reportDrawFinished
通知WMS客户端已经完成绘制。
WMS进行系统窗口的状态刷新以及动画处理并最终将Surface显示出来
WMS窗口添加之后还没有创建Surface此时mDrawState状态为NO_SURFACE
开启同步屏障,进行view的测量布局绘制requestLayout();//
客户端通知WMS创建一个窗口并添加到WindowTokenres
mWindowSession.addToDisplayAsUser(mWindow,
mWindowAttributes,getHostVisibility(),
userId,mInsetsController.getRequestedVisibilities(),
{mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);}}...//
attrs.getTitle();mSyntheticInputStage
SyntheticInputStage();...}}}客户端总结
WindowManager是一个接口类负责窗口的管理增、删、改WindowManagerImplWindowManager的实现类但是他把对于窗口的具体管理操作交给WindowManagerGlobal来处理。
WindowManagerGlobal是一个单例类实现了窗口的添加、删除、更新的逻辑。
ViewRootImpl通过IWindowSession与WMS进行通信。
其内部类W实现了WMS与ViewRootImpl的通信。
requestedVisibilities,InputChannel
outInsetsState,InsetsSourceControl[]
AIDL判断是否已添加已添加则返回错误判断是否子窗口的type
将父窗口的tokenIWindow放到attrs.token依然从
是否为null.也就是是否子窗口如果有父窗口对获取对应的WindowToken
requestedVisibilities,InputChannel
outInsetsState,InsetsSourceControl[]
{Arrays.fill(outActiveControls,
PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY)
mPolicy.checkAddPermission(attrs.type,
getDisplayContentOrCreate(displayId,
WindowManagerGlobal.ADD_INVALID_DISPLAY;}if
(!displayContent.hasAccess(session.mUid))
Aborting.,displayContent.getDisplayId());return
WindowManagerGlobal.ADD_INVALID_DISPLAY;}//
AIDL接口用于wms和应用交互通知,判断是否添加已添加在map会保存if
(mWindowMap.containsKey(client.asBinder()))
WindowManagerGlobal.ADD_DUPLICATE_ADD;}//
WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;}if
WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;}}...ActivityRecord
根据客户端传来的token获取windowToken*///attrs.token去DisplayContent.mTokenMap中去取WindowToken//那么WindowToken是什么时候加入到mTokenMap中的呢//这就要追溯到Activity的启动时加入到DisplayContent中//在ActivityStarter.startActivityInner中调用addOrReparentStartingActivity通过addChild一步步调用到WindowContainert中。
//在调用setParent,最终通过onDisplayChanged将ActivityRecord加入到DisplayContent.mTokenMap中WindowToken
displayContent.getWindowToken(hasParent
如果为空则判断是否有父窗口有用父亲的mToken没有的话创建对应的
WindowToken(WindowManagerService
ownerCanManageAppTokens,boolean
persistOnEmpty;mOwnerCanManageAppTokens
ownerCanManageAppTokens;mRoundedCornerOverlay
roundedCornerOverlay;mFromClientToken
DisplayContent为根节点的WindowContainer层级结构中if
userId,session.mCanAddInternalSystemWindow);if
WindowManagerGlobal.ADD_APP_EXITING;}if
WindowManagerGlobal.ADD_INVALID_DISPLAY;}final
displayContent.getDisplayPolicy();displayPolicy.adjustWindowParamsLw(win,
win.mAttrs);win.setRequestedVisibilities(requestedVisibilities);attrs.flags
sanitizeFlagSlippery(attrs.flags,
displayPolicy.validateAddingWindowLw(attrs,
INPUT_FEATURE_NO_INPUT_CHANNEL)
{win.openInputChannel(outInputChannel);}调用
SurfaceSession用于SurfaceFlinger通信。
在将该clinet
userId,session.mCanAddInternalSystemWindow);...final
displayContent.getDisplayPolicy();displayPolicy.adjustWindowParamsLw(win,
win.mAttrs);win.setRequestedVisibilities(requestedVisibilities);attrs.flags
sanitizeFlagSlippery(attrs.flags,
displayPolicy.validateAddingWindowLw(attrs,
INPUT_FEATURE_NO_INPUT_CHANNEL)
{win.openInputChannel(outInputChannel);}...//
创建SufaceSession用于SurfaceFlinger通信win.attach();//
mWindowMap保存了每个WindowState和客户端窗口的映射关系客户端应用请求窗口操作时//
通过mWindowMap查询到对应的WindowStatemWindowMap.put(client.asBinder(),
win);win.initAppOpsState();final
mPmInternal.isPackageSuspended(win.getOwningPackage(),UserHandle.getUserId(win.getOwningUid()));win.setHiddenWhileSuspended(suspended);final
!mHidingNonSystemOverlayWindows.isEmpty();win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);boolean
将WindowState加入到WindowTokenwin.mToken.addWindow(win);WMS窗口添加之后还没有创建Surface此时mDrawState状态为NO_SURFACE
参数意义window是WMS与客户端通信的Binderattrs窗口的布局属性根据attrs提供的属性来布局窗口requestedWidthrequestedWidthrequestedHeightrequestedHeightviewFlags窗口的可见性。
包括VISIBLE0view可见INVISIBLE4view不可见但是仍然占用布局空间GONE8view不可见不占用布局空间outFrames返回给客户端的保存了重新布局之后的位置与大小flags定义一些布局行为mergedConfiguration相关配置信息outSurfaceControl返回给客户端的surfaceControloutInsetsState用来保存系统中所有Insets的状态outActiveControlsInSetsSourceControl数组
oldVisibility变量用于后续的判断。
在判断布局的可见性是否变化。
将
从mWindowMap根据client获取对应的WindowStatefinal
获取DisplayContent、DisplayPolicyfinal
displayContent.getDisplayPolicy();WindowStateAnimator
根据客户端请求的窗口大小设置WindowState的requestedWidth,
并设置WindowState.mLayoutNeeded为truewin.setRequestedSize(requestedWidth,
根据请求的宽带和高度窗口缩放比例win.setWindowScale(win.mRequestedWidth,
win.mAttrs.surfaceInsets.bottom
{winAnimator.setOpaqueLocked(false);}//
获取原来window的可见性此时为INVISIBLEfinal
win.hasWallpaper();wallpaperMayMove
{winAnimator.mSurfaceController.setSecure(win.isSecureLocked());}//
代表现在没有surface但应该很快就有标志位win.mRelayoutCalled
将当前窗口的可见性有原来的INVISIBLE调整为VISIBLEwin.setViewVisibility(viewVisibility);调用
将displayContent中的布局标志为mLayoutNeeded置为truewin.setDisplayLayoutNeeded();...//
view可见且activityRecord不为空或者布局类型为TYPE_APPLICATION_STARTING或者窗口已经告诉客户端可以显示final
win.mActivityRecord.isClientVisible());...//
进入creatSurfaceControl开始创建SurfaceControlresult
createSurfaceControl(outSurfaceControl,
{displayContent.getInputMonitor().updateInputWindowsLw(true
/*force*/);ProtoLog.w(WM_ERROR,Exception
e);Binder.restoreCallingIdentity(origId);return
createSurfaceControl(SurfaceControl
RELAYOUT_RES_SURFACE_CHANGED;}WindowSurfaceController
{Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
WindowStateAnimator用来帮助WindowState管理animator和surface基本操作的//
WMS将创建的surfaceContorl的操作交给windowAnimator来处理surfaceController
winAnimator.createSurfaceLocked(win.mAttrs.type);}
{Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}if
将WMS的SurfaceControl赋值给客户端的outSurfaceControlsurfaceController.getSurfaceControl(outSurfaceControl);ProtoLog.i(WM_SHOW_TRANSACTIONS,
win);outSurfaceControl.release();}return
mSurfaceController;}w.setHasSurface(false);if
DRAW_PENDINGresetDrawState();...try
attrs.getTitle().toString()为当前activity的全路径名//
flags为surface创建的标志位如HIDDED(0x04,surface创建为隐藏)//
SKIP_SCREENSHOT(0x040截屏时跳过此图层将不会包含在非主显示器上),//
SECURE(0X080,禁止复制表面的内容屏幕截图和次要的非安全显示将呈现黑色内容而不是surface内容)等//
attrs.type为窗口类型mSurfaceController
WindowSurfaceController(attrs.getTitle().toString(),
windowType);mSurfaceController.setColorSpaceAgnostic((attrs.privateFlags
WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC)
format;w.setHasSurface(true);}...return
WindowSurfaceController的构造构造方法会调用
Dimming).*/SurfaceControl.Builder
makeChildSurface(WindowContainer
p.makeChildSurface(child).setParent(mSurfaceControl);}调用
窗口尺寸的计算以及Surface的状态变更,确定所有窗口的Surface的如何摆放如何显示、显示在什么位置、显示区域多大的一个入口方法。
该部分处理有关窗口布局循环的逻辑。
该部分处理Surface的状态变更以及调用layoutWindowLw的流程。
在调用
fillClientWindowFramesAndConfiguration
窗口尺寸的计算以及Surface的状态变更,确定所有窗口的Surface的如何摆放如何显示、显示在什么位置、显示区域多大的一个入口方法//
2.该部分处理Surface的状态变更以及调用layoutWindowLw的流程。
//
3.计算窗口位置大小。
mWindowPlacerLocked.performSurfacePlacement(true
填充计算好的frame返回给客户端更新mergedConfiguration对象win.fillClientWindowFramesAndConfiguration(outFrames,
windowState的setDisplayLayoutNeeded.将DisplayContent中mLayoutNeeded置为true标志位是判断是否进行窗口大小尺寸计算的条件之一
Binder.clearCallingIdentity();try
1.根据客户端的Binder在mWindowMap中获取对应的WindowStateWindowState
false);ProtoLog.d(WM_DEBUG_ADD_REMOVE,
win.mWinAnimator.drawStateToString()
2.finishDrawing执行mDrawState的状态更变if
win.finishDrawing(postDrawTransaction))
{win.getDisplayContent().pendingLayoutChanges
|WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;}//
3.将DisplayContent中mLayoutNeeded置为true//
该标志位是判断是否进行窗口大小尺寸计算的条件之一win.setDisplayLayoutNeeded();//
4.请求进行布局刷新mWindowPlacerLocked.requestTraversal();}}}
{Binder.restoreCallingIdentity(origId);}}调用
mPerformSurfacePlacement任务里面又会执行
performSurfacePlacementLoop,最重要又会调用
RootWindowContainer的performSurfacePlacement
将该标志位置为true表示正在处于布局过程中mInLayout
调用RootWindowContainer的performSurfacePlacement()方法对所有窗口执行布局操作mService.mRoot.performSurfacePlacement();mInLayout
(mService.mRoot.isLayoutNeeded())
该方法中会将mTraversalScheduled标志位设置位truerequestTraversal();}
判断是否有焦点变化如果有更新焦点开启事务获取GlobalTransactionWrapper对象调用
方法会进行屏幕的水印位置处理之外还会遍历下面的每个displayContent
applySurfaceChangesTransaction()
1.水印、StrictMode警告框以及模拟器显示的布局//获取手机默认DisplayContent的信息final
mWmService.getDefaultDisplayContentLocked();final
defaultDc.getDisplayInfo();final
{mWmService.mWatermark.positionSurface(defaultDw,
mDisplayTransaction);}//布局StrictMode警告框if
{mWmService.mStrictModeFlash.positionSurface(defaultDw,
(mWmService.mEmulatorDisplayOverlay
{mWmService.mEmulatorDisplayOverlay.positionSurface(defaultDw,
defaultDh,mWmService.getDefaultDisplayRotation(),
2.遍历RootWindowContainer下所有DisplayContent执行其applySurfaceChangesTransaction()final
mChildren.get(j);dc.applySurfaceChangesTransaction();}//
to.mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction);SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction);}applySurfaceChangesTransaction方法
mApplySurfaceChangesTransaction里面又会调用
winAnimator.commitFinishDrawingLocked
applySurfaceChangesTransaction()
mWmService.mWindowPlacerLocked;...do
1.执行布局该方法最终会调用performLayoutNoTrace计算窗口的布局参数if
2.遍历所有窗口主要是改变surface的状态。
mDrawState变更为HAS_DRAW流程forAllWindows(mApplySurfaceChangesTransaction,
{Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}...//
3.处理各个surface的位置、大小以及是否要在屏幕上显示等。
后面finishDrawing()流程中再跟踪prepareSurfaces();...}调用
HAS_DRAWN。
遍历所有DisplayContent如果壁纸有变化更新壁纸在一次此处理焦点变化如果过程中size或者位置变化则通知客户端重新relayout销毁不可见的窗口
performSurfacePlacementNoTrace()
false;mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
/*updateInputWindows*/);}...Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
开启事务获取GlobalTransactionWrapper对象mWmService.openSurfaceTransaction();try
2.执行窗口尺寸计算surface状态变更等操作applySurfaceChangesTransaction();}
关闭事务mWmService.closeSurfaceTransaction(performLayoutAndPlaceSurfaces);Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);if
performLayoutAndPlaceSurfaces);}}...//
3.将Surface状态变更为HAS_DRAWN触发App触发动画。
checkAppTransitionReady(surfacePlacer);//
4.遍历所有DisplayContent如果壁纸有变化更新壁纸final
mWmService.getRecentsAnimationController();if
{recentsAnimationController.checkAnimationReady(defaultDisplay.mWallpaperController);}for
(displayContent.mWallpaperMayChange)
{ProtoLog.v(WM_DEBUG_WALLPAPER,
Adjusting);displayContent.pendingLayoutChanges
FINISH_LAYOUT_REDO_WALLPAPER;if
{surfacePlacer.debugLayoutRepeats(WallpaperMayChange,displayContent.pendingLayoutChanges);}}}//
false;mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,false
{defaultDisplay.pendingLayoutChanges
{surfacePlacer.debugLayoutRepeats(mLayoutNeeded,defaultDisplay.pendingLayoutChanges);}}//
6.如果过程中size或者位置变化则通知客户端重新relayouthandleResizingWindows();if
{ProtoLog.v(WM_DEBUG_ORIENTATION,With
orientationChangeComplete%b,mOrientationChangeComplete);}if
(mWmService.mWindowsFreezingScreen
{mWmService.mWindowsFreezingScreen
WINDOWS_FREEZING_SCREENS_NONE;mWmService.mLastFinishedFreezeSource
mLastWindowFreezeSource;mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);}mWmService.stopFreezingDisplayLocked();}//
mWmService.mDestroySurface.size();if
mWmService.mDestroySurface.get(i);win.mDestroying
(displayContent.mInputMethodWindow
{displayContent.setInputMethodWindowLocked(null);}if
(displayContent.mWallpaperController.isWallpaperTarget(win))
{displayContent.pendingLayoutChanges
FINISH_LAYOUT_REDO_WALLPAPER;}win.destroySurfaceUnchecked();}
0);mWmService.mDestroySurface.clear();}...}注WindowStateAnimator的commitFinishDrawingLocked()方法中如果是应用通过WindowManager中的addView的方式创建窗口则不会有ActivityRecord或者该窗口类型为启动窗口则直接调用result
mWin.performShowLocked();即WindowState的performShowLocked()方法改变窗口状态为HAS_DRAW否则会从RootWindowContainer的checkAppTransitionReady方法逐步调用到performShowLocked()
WMS为了管理窗口的显示进度在WindowStateAnimator中定义了mDrawState来描述Surface所处的状态。
主要有如下五种状态
状态时机NO_SURFACEWMS添加窗口,即调用addWindow之后还没有创建SurfacemDrawState处于该状态DRAW_PENDINGapp调用relayoutWindow创建Surface后但是Surface还没有进行绘制mDrawState处于该状态COMMIT_DRAW_PENDINGapp完成Surface的绘制调用finishDrawing将mDrawState设置为该状态READY_TO_SHOW在performSurfacePlacement过程中会将所有处于COMMIT_DRAW_PENDING状态的mDrawState变更为READY_TO_SHOWHAS_DRAW若准备显示窗口WMS执行performShowLocked将mDrawState设置为该状态
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback