WMS--窗口创建流程整理

参考:http://www.cnblogs.com/samchen2009/p/3364327.html





                                                                      《图3》Choreographer处理Vsync流程图
                                                                      《图5》
                                                  
    1)1号区域为OverscanScreen,包含了屏幕上的overscan区,相当于整个屏幕大小
     2)2号区域为RestrictedOverscanScreen,包含overscan,不包含导航栏。因些上端到达屏幕的顶部,下端则只到导航栏的顶部
     3)3号区域为RestrictedScreen,不包含屏幕上的overscan,不包含导航栏
     4)4区域为UnrestrictedScreen,不包含Overscan,包含状态栏和导航栏
     5)5区域为StableFullscreen,包含状态栏,不包含导航栏
     6)6区域为Decor,不包含状态栏,不包含导航栏,包含输入法区域(System区域、Stable区域、Content区域同等) 
     7)7区域为Curren,不包含状态栏,不包含导航栏,不包含输入法区域
     pf(ParentFrame):表示窗口的父窗的大小
     df(DeviceFrame):设备的屏幕大小
     of(OverScanFrame):设备的屏幕大小,和df的值一样
     cf(ContentFrame):窗口内容区域的大小
     vf(VisibleFrame):窗口可见区域的大小
     dcf(DecorFrame):装饰区域的大小。除去状态栏条和导航条的区域
     pf、df、of不包括导航栏;cf、vf不包含导航栏、状态栏、输入法;sf不包含导航栏、状态栏

          

1、addWindow()函数
//在mTokenMap中查找windowToken
WindowToken token = mTokenMap.get(attrs.token);

//子窗口,寻找父窗口
if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
attachedWindow = windowForClientLocked(null, attrs.token, false);

//创建WindowState对象
WindowState win = new WindowState(this, session, client, token,attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);

//调整窗口参数
mPolicy.adjustWindowParamsLw(win.mAttrs);
//检查和设置窗口是否能够让其他的用户看见
win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
//检查特殊类型的窗口是否能添加
res = mPolicy.prepareAddWindowLw(win, attrs);

//如果窗口接受输入,注册inputChannel
String name = win.makeInputChannelName();
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
win.setInputChannel(inputChannels[0]);
inputChannels[1].transferTo(outInputChannel);
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);

//加入WindowState对象到列表中。mWindowMap列表中保存了系统中所有顶层窗口的信息
win.attach();
  mWindowMap.put(client.asBinder(), win);

//把WindowState按顺序加到mWindows。DisplayContent类的mWindows列表按Z序保存了每个窗口
addWindowToListInOrderLocked(win, true);

//计算Content区域大小
mPolicy.getInsetHintLw(win.mAttrs, mRotation, outContentInsets, outStableInsets,outOutsets);

//如果窗口能接受输入计算是否引起焦点变化  
if (win.canReceiveKeys()) {
  focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
  false /*updateInputWindows*/);
  if (focusChanged) {
  imMayMove = false;
  }
  }

//重新计算z轴的位置 
assignLayersLocked(displayContent.getWindowList());

//设置和更新Input焦点变化
if (focusChanged) {
  mInputMonitor.setInputFocusLw(mCurrentFocus, false /*updateInputWindows*/);
  }
  mInputMonitor.updateInputWindowsLw(false /*force*/);

1.1、win.attach()函数
mSurfaceSession = new SurfaceSession();
mService.mSessions.add(this);
mNumWindow++;

2、invalidate
  View.invalidate-> View.invalidateInternal-> ViewParent.invalidateChild
  ViewRootImpl.invalidateChildInParent-> ViewRootImpl.scheduleTraversals
  mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);


3、performTraversals()函数

4、relayoutWindow()函数
//获取窗口WindowState
WindowState win = windowForClientLocked(session, client, false);

//如果请求窗口大小跟实际WindowState大小不一样,则以请求大小为标准
if (viewVisibility != View.GONE && (win.mRequestedWidth != requestedWidth
|| win.mRequestedHeight != requestedHeight)) {
win.mLayoutNeeded = true;
win.mRequestedWidth = requestedWidth;
win.mRequestedHeight = requestedHeight;
}
/**对于处于可见状态的窗口处理:
*1、如果窗口没有Surface,则为其创建一块Surface
*2、如果客户端改变了窗口的色彩格式(由LayoutParams.format指定)发生了变化则为其重新创建一块指定格式的Surface
*3、如果窗口尚未被显示,并且客串的客户端已经完成了绘制,则为其启动一个淡入动画
*/
if (viewVisibility == View.VISIBLE &&(win.mAppToken == null || !win.mAppToken.clientHidden)) {
winAnimator.mEnteringAnimation = true;
//执行进入动画
if (win.isDrawnLw() && okToDisplay()) {
  winAnimator.applyEnterAnimationLocked();
  }
//创建Surface
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
} else {
/*对于处于非可见状态下的窗口,主要的处理如下:
*1、标记WindowState的mExiting属性为true
*2、如果窗口目前正被显示,则为其启动一个淡出动画
*3、释放客户端所持有的Surface对象,自此之后,客户端无法再更新窗口的内容
*/
if (win.isWinVisibleLw() &&winAnimator.applyAnimationLocked(transit, false)) {
  focusMayChange = isDefaultDisplay;
  win.mExiting = true;
  }
outSurface.release();

//更新焦点窗口
if (focusMayChange) {
  if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
  false /*updateInputWindows*/)) {
  imMayMove = false;
  }
  }
//见<<深入理解Android 卷3>>分析,参考 《图5》
performLayoutAndPlaceSurfacesLocked();

//返回布局结果
outFrame.set(win.mCompatFrame);
outOverscanInsets.set(win.mOverscanInsets);
outContentInsets.set(win.mContentInsets);
outVisibleInsets.set(win.mVisibleInsets);
outStableInsets.set(win.mStableInsets);
outOutsets.set(win.mOutsets);













  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值