当前位置: 首页 > news >正文

营销型网站的盈利模式sem 优化价格

营销型网站的盈利模式,sem 优化价格,做天猫网站价格,东莞seo优化联系电话Android 的 WMS(Window Manager Service)是一个关键组件,负责管理窗口的创建、显示、布局和交互等。Window 的操作有两大部分,一部分是 WindowManager 来处理,一部分是 WMS 来处理,如下图所示: …

        Android 的 WMS(Window Manager Service)是一个关键组件,负责管理窗口的创建、显示、布局和交互等。Window 的操作有两大部分,一部分是 WindowManager 来处理,一部分是 WMS 来处理,如下图所示:

        WindowManager 中,通过 WindowManagerGlobal 创建 ViewRootImpl ,也就是 View 的根。在 ViewRootImpl 中完成对 View 的绘制等操作,然后通过 IPC 获取到 Session,最终通过 WMS 来进行处理。WindowManager 部分的管理流程前面已经介绍,这里我们来看一下 WMS 对 Window 的管理。

一、调用流程

1、WM到WMS

        我们都知道 Window 的添加最后是通过 ViewRootImpl.addTodisplay 方法来完成的,我们先来看一下:

ViewRootImpl

源码位置:/frameworks/base/core/java/android/view/ViewRootImpl.java

final IWindowSession mWindowSession;public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) {synchronized (this) {if (mView == null) {……try {……res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(), userId,mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,mTempControls);}……}}
}

        这里调用了 mWindowSession.addToDisplayAsUser 来完成最后的添加,可以看到  IWindowSession 是一个接口类,真正实现该接口的是 Session 类。

Session

源码位置:/frameworks/base/services/core/java/com/android/server/wm/Session.java

final WindowManagerService mService;@Override
public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,int viewVisibility, int displayId, int userId, InsetsState requestedVisibility,InputChannel outInputChannel, InsetsState outInsetsState,InsetsSourceControl[] outActiveControls) {return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,requestedVisibility, outInputChannel, outInsetsState, outActiveControls);
}

        可以看到,最终是通过 WMS 来完成添加的。需要注意的是,WMS 并不关心 View 的具体内容,他只关心各个应用显示的界面大小、层级值等,这些数据到包含在 WindowManager.LayoutParams 中。也就是上面的 atrs 属性。

        addWindow 的第二个参数是一个 IWindow 类型,这是 App 暴露给 WMS 的抽象实例,在 ViewRootImp 中实例化,与 ViewRootImpl 一一对应,同时也是 WMS 向 App 端发送消息的 Binder 通道。

二、WMS窗口添加

WindowManagerService

源码位置:/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,int displayId, int requestUserId, InsetsState requestedVisibility,InputChannel outInputChannel, InsetsState outInsetsState,InsetsSourceControl[] outActiveControls) {Arrays.fill(outActiveControls, null);int[] appOp = new int[1];final boolean isRoundedCornerOverlay = (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;// 1.检查权限,mPolicy的实现类是PhoneWindowManager。int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName, appOp);if (res != ADD_OKAY) {return res;}……synchronized (mGlobalLock) {……// 2.通过displayId获取Window要添加到哪个DisplayContent。final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);if (displayContent == null) {// 没有找到对应的显示屏幕return WindowManagerGlobal.ADD_INVALID_DISPLAY;}……// 3.判断type的窗口类型(100-1999),如果是子类型,必须要有父窗口,并且父窗口不能是子窗口类型。if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {parentWindow = windowForClientLocked(null, attrs.token, false);if (parentWindow == null) {// 试图添加带有非窗口令牌的窗口return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;}if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {// 试图添加带有子标记的窗口return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;}}……ActivityRecord activity = null;final boolean hasParent = parentWindow != null;// 4.对子窗口使用与父窗口使用的令牌,因此我们可以对它们应用相同的策略。WindowToken token = displayContent.getWindowToken(hasParent ? parentWindow.mAttrs.token : attrs.token);// 如果这是一个子窗口,与父窗口类型相同的检查规则。final int rootType = hasParent ? parentWindow.mAttrs.type : type;boolean addToastWindowRequiresToken = false;// 5. token为null。if (token == null) {if (hasParent) {// 对子窗口使用现有的父窗口令牌。token = parentWindow.mToken;} else if (mWindowContextListenerController.hasListener(windowContextToken)) {// 如果用户提供的话,尊重窗口上下文令牌final IBinder binder = attrs.token != null ? attrs.token : windowContextToken;final Bundle options = mWindowContextListenerController.getOptions(windowContextToken);token = new WindowToken.Builder(this, binder, type).setDisplayContent(displayContent).setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow).setRoundedCornerOverlay(isRoundedCornerOverlay).setFromClientToken(true).setOptions(options).build();} else {// 6.且不是应用窗口或者是其他类型的窗口,则窗口就是系统类型(例如 Toast)。// 进行隐式创建 WindowToken,这说明我们添加窗口时是可以不向WMS提供WindowToken的。final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();token = new WindowToken.Builder(this, binder, type).setDisplayContent(displayContent).setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow).setRoundedCornerOverlay(isRoundedCornerOverlay).build();}} else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {// 7、判断是否为应用窗口,如果是,将WindowToken转换为应用程序窗口的ActivityRecord。activity = token.asActivityRecord();if (activity == null) {// 试图添加带有非应用程序令牌的窗口return WindowManagerGlobal.ADD_NOT_APP_TOKEN;} else if (activity.getParent() == null) {// 试图添加具有退出应用程序的窗口return WindowManagerGlobal.ADD_APP_EXITING;} else if (type == TYPE_APPLICATION_STARTING) {if (activity.mStartingWindow != null) {// 试图用已经存在的开始窗口向令牌添加开始窗口return WindowManagerGlobal.ADD_DUPLICATE_ADD;}if (activity.mStartingData == null) {// 试图向令牌添加起始窗口,但已被清除return WindowManagerGlobal.ADD_DUPLICATE_ADD;}}} else if (rootType == TYPE_INPUT_METHOD) {if (token.windowType != TYPE_INPUT_METHOD) {// 试图添加带有错误令牌的输入法窗口return WindowManagerGlobal.ADD_BAD_APP_TOKEN;}}……// 8.创建WindowState,保存窗口的所有状态信息,在WMS中,WindowState与窗口是一一对应的关系。final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], attrs, viewVisibility, session.mUid, userId, session.mCanAddInternalSystemWindow);// 9.判断请求添加窗口的客户端是否已经死亡,如果死亡则不会执行下面逻辑。if (win.mDeathRecipient == null) {return WindowManagerGlobal.ADD_APP_EXITING;}if (win.getDisplayContent() == null) {return WindowManagerGlobal.ADD_INVALID_DISPLAY;}final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();// 10.根据窗口的type类型对窗口的LayoutParams的一些成员变量进行修改。displayPolicy.adjustWindowParamsLw(win, win.mAttrs);win.updateRequestedVisibility(requestedVisibility);// 11.准备将窗口添加到系统中res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);if (res != ADD_OKAY) {return res;}……// 12.将WindowState添加到mWindowMap中,mWindowMap是各种窗口的集合。mWindowMap.put(client.asBinder(), win);……boolean imMayMove = true;// 13.添加窗口。将WindowState添加到对应的WindowToken中(实际上就是保存在WindowToken的父类 WindowContainer),这样WindowToken就包含了相同组件的WindowState。win.mToken.addWindow(win);}return res;
}

        WMS 的 addWindow 方法返回的是 addWindow 的各种状态,例如添加成功、失败、无效的 display 等,这些状态定义在 WindowManagerGloabl 中 。

        通过上面的流程,App 到 WMS 注册窗口的流程就完了,WMS 为窗口创建了用来描述状态的 WindowState,接下来就会为新建的窗口显示次序,然后再去申请 Surface,才算是真正的分配了窗口。

        这里对 WMS 的 addWindow 流程做一个总结 :

  • 首先检查权限

  • 接着从 mRoot(RootWindowContainer)中获取 DisplayContent ,如果没有就会根据 displayId 创建一个新的 DisplayContent

  • 接着就是 type 类型的判断,如果是子类型,就必须要获取到他的父窗口,

  • 接着使用 DisplayContent 获取当前或者父窗口获取 token,如果为 null 就排除子窗口和其他的窗口,剩下的就是可以不用携带 token 的窗口,WMS 会隐式的创建窗口 token。如果不等于 null 就判断是应用窗口就将 token 转为 ActivityRecord,后面还有一大堆窗口判断,只要是不满足就直接 return。

  • 类型判断完成后,就会创建 WindowState,并且传入 WMS、IWindow、token 等。WindowState 里面保存了窗口的所有信息。WindowState 与窗口一一对应。

  • 接着就执行调用了 WindowState 的 attache 、initAppOpsState 等方法。WindowState 创建完成后就会被添加到 mWindowMap 中,可以 IWindow 的 Binder 为 key,WindowState 为 value 添加进去。

  • 最后就是 win.mToken.addWindow(win) ,然后将 WindowState 添加到 WindowToken 中。因为 WindowToken 是可以复用的,所以这里的关系就是,每个 WindowToken 都会保存对应的 WindowState,而每个 WindowState 也都会都持有 WindowToekn。

http://www.tj-hxxt.cn/news/11089.html

相关文章:

  • 做庭院景观的那个网站推广好web网页
  • 单仁做的网站宁波网站关键词优化排名
  • 廊坊免费网站建设模板郑州seo招聘
  • 网站建设哪个比较好google app下载
  • wordpress on lnmpseo关键词优化最多可以添加几个词
  • 最快做网站的语言百度百家
  • 网站建设 定制商城 小程序开发简述如何优化网站的方法
  • 化妆品网站建设的目的中国行业数据分析网
  • 自己的网站怎么做app网站seo百度百科
  • 东莞视频网站制作百度指数是什么意思
  • 网站建设 需要注意什么石家庄
  • wordpress tint2.5乐陵seo外包
  • 有什么设计网站推荐品牌推广活动方案
  • 哈尔滨特优网络科技有限公司seo 的作用和意义
  • dnf做心悦宠物的网站市场营销专业课程
  • 统计网站的代码如何快速提升自己
  • 长沙seo网站管理小程序开发框架
  • 职业学院思想政治网站建设百度学术搜索入口
  • 衡水商城网站建设论坛排名
  • 网站建设规划模板色盲测试图
  • 招生网站建设板块怎样利用互联网进行网络推广
  • 做网站的工作怎么样廊坊关键词快速排名
  • 电商网站分析报告竞价托管代运营公司
  • 新干网站新干今年有哪些重大建设北京百度关键词排名
  • 做网站知识点专门代写平台
  • 镇江网站建设推广产品营销策略怎么写
  • 品牌建设存在问题深圳整站seo
  • 网站佣金怎么做分录百度推广和百度竞价有什么区别
  • 做c 题的网站seo营销网站的设计标准
  • c++可以做网站吗搜索引擎优化学习