android WMS—— WindowToken

WindowToken

WindowToken作为一个window的句柄,从其windowToken.java中其继承WindowContainer<WindowState>以及其成员中的IBinder token可以看出:

  • WindowToken将属于同一个应用组件的窗口组织在了一起
  • 包含一个IBinder对象,来对应Android端的Window

当生成一个新的windowToken,意味着app端生成一个新的window,需要将该window添加到windowmanager,并更新displayContent的窗体列表,其从windowToken构造函数出发,其流程如图:


windowToken构造函数.jpg

reParentWindowToken函数中对该WindowToken判断是否已经绑定在该displayContent,如果绑定就不在添加;否则如果绑定在别的displayContent中,则将其从原有的displayContent中删除,并将其从parent container中删除,然后在添加。
addWindowToken将该windowToken绑定到displayContent中

    private void addWindowToken(IBinder binder, WindowToken token) {
        final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
        ......
        //所有的WindowToken添加到TokenMap中
        mTokenMap.put(binder, token);
       //如果不是Activity对应的WindowToken,
       //根据WindowToken传进来的windowType来判断
        if (token.asAppWindowToken() == null) {
            // Add non-app token to container hierarchy on the display. App tokens are added through
            // the parent container managing them (e.g. Tasks).
            switch (token.windowType) {
                case TYPE_WALLPAPER: //壁纸
                    mBelowAppWindowsContainers.addChild(token);
                    break;
                case TYPE_INPUT_METHOD:
                case TYPE_INPUT_METHOD_DIALOG: //输入法弹窗
                    mImeWindowsContainers.addChild(token);
                    break;
                default: //剩下的如StatusBar
                    mAboveAppWindowsContainers.addChild(token);
                    break;
            }
        }
    }

WMS声明WindowToken
在应用中通过WMS.addWindowToken声明生成windowToken

    @Override
    public void addWindowToken(IBinder binder, int type, int displayId) {
        if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
        }

        synchronized(mWindowMap) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            WindowToken token = dc.getWindowToken(binder);
            if (token != null) {
                Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
                        + " for already created window token: " + token
                        + " displayId=" + displayId);
                return;
            }
            if (type == TYPE_WALLPAPER) {
                new WallpaperWindowToken(this, binder, true, dc,
                        true /* ownerCanManageAppTokens */);
            } else {
                new WindowToken(this, binder, type, true, dc, true /* ownerCanManageAppTokens */);
            }
        }
    }

其中WallpaperWindowToken继承与WindowToken,并将该windowToken传递给WMS.mWallpaperController.addWallpaperToken 以便WMS管理壁纸

AppWindowToken

AppWindowToken继承与WindowToken,用来描述Activity组件窗口。AppWindowToken服务于activity,因此其生成也是在AMS中。在AppWindowToken中新增 IApplicationToken appToken成员。


appWindowToken.jpg

AppWindowToken后进入WindowToken的流程,将在displayContent中的tokenMap保存了ActivityRecord的token,key为token(IAppWindowToken),value为WindowToken

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容