Android 12系统源码_窗口管理(四)窗口令牌WindowToken和窗口状态WindowState

前言

在 Android 系统中,WindowToken(窗口令牌) 和 WindowState(窗口状态)是两个重要的类,用于管理窗口视图的显示和布局。
WindowToken用于标识窗口中的视图层级,而WindowState用于管理窗口的状态和属性。这两个类在 Android 系统中起着重要的作用,帮助确保应用程序界面正确地显示和布局,只有认识了这两个类我们才能更好的理解WindowManagerService这个服务。

一、WindowToken(窗口令牌)

1、介绍

  • WindowToken主要用于标识Android系统中窗口中的特定视图层级,它代表了窗口中的一个视图层级的令牌。
  • 在 Android 中,窗口是视图层级的容器,用于组织和管理应用程序界面中的不同元素。每个窗口都有一个关联的 WindowToken,用于标识该窗口中的视图层级。
  • WindowToken 通常与窗口管理器一起使用,用于跟踪窗口的属性和状态,并确保正确地显示和管理窗口。
  • 例如,当应用程序中有多个窗口(例如活动、对话框、弹出窗口等)时,每个窗口都有自己的 WindowToken,用于标识其包含的视图层级。

2、WindowToken这个类如下所示。

frameworks/base/services/core/java/com/android/server/wm/WindowToken.java

class WindowToken extends WindowContainer<WindowState> {

    final IBinder token;
    final int windowType;
    final Bundle mOptions;
    private final boolean mFromClientToken;
    private boolean mClientVisible;
    
    protected WindowToken(WindowManagerService service, IBinder _token, int type,
            boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens) {
        this(service, _token, type, persistOnEmpty, dc, ownerCanManageAppTokens,
                false /* roundedCornerOverlay */, false /* fromClientToken */, null /* options */);
    }

    protected WindowToken(WindowManagerService service, IBinder _token, int type,
            boolean persistOnEmpty, DisplayContent dc, boolean ownerCanManageAppTokens,
            boolean roundedCornerOverlay, boolean fromClientToken, @Nullable Bundle options) {
        super(service);
        token = _token;
        windowType = type;
        mOptions = options;
        mPersistOnEmpty = persistOnEmpty;
        mOwnerCanManageAppTokens = ownerCanManageAppTokens;
        mRoundedCornerOverlay = roundedCornerOverlay;
        mFromClientToken = fromClientToken;
        if (dc != null) {
            dc.addWindowToken(token, this);
        }
    }

    static class Builder {
        private final WindowManagerService mService;
        private final IBinder mToken;
        @WindowType
        private final int mType;

        private boolean mPersistOnEmpty;
        private DisplayContent mDisplayContent;
        private boolean mOwnerCanManageAppTokens;
        private boolean mRoundedCornerOverlay;
        private boolean mFromClientToken;
        @Nullable
        private Bundle mOptions;

        Builder(WindowManagerService service, IBinder token, int type) {
            mService = service;
            mToken = token;
            mType = type;
        }

        /** @see WindowToken#mPersistOnEmpty */
        Builder setPersistOnEmpty(boolean persistOnEmpty) {
            mPersistOnEmpty = persistOnEmpty;
            return this;
        }

        /** Sets the {@link DisplayContent} to be associated. */
        Builder setDisplayContent(DisplayContent dc) {
            mDisplayContent = dc;
            return this;
        }

        /** @see WindowToken#mOwnerCanManageAppTokens */
        Builder setOwnerCanManageAppTokens(boolean ownerCanManageAppTokens) {
            mOwnerCanManageAppTokens = ownerCanManageAppTokens;
            return this;
        }

        /** @see WindowToken#mRoundedCornerOverlay */
        Builder setRoundedCornerOverlay(boolean roundedCornerOverlay) {
            mRoundedCornerOverlay = roundedCornerOverlay;
            return this;
        }

        /** @see WindowToken#mFromClientToken */
        Builder setFromClientToken(boolean fromClientToken) {
            mFromClientToken = fromClientToken;
            return this;
        }

        /** @see WindowToken#mOptions */
        Builder setOptions(Bundle options) {
            mOptions = options;
            return this;
        }

        WindowToken build() {
            return new WindowToken(mService, mToken, mType, mPersistOnEmpty, mDisplayContent,
                    mOwnerCanManageAppTokens, mRoundedCornerOverlay, mFromClientToken, mOptions);
        }
    }
 }
  • WindowToken将属于同一个应用的组件窗口组织在一起。

所谓的应用组件可以是 Activity、InputMethod、Wallpaper以及Dream。在WMS对窗口的管理过程中,用 WindowToken指代一个应用组件。例如在进行窗口ZOrder排序时,属于同一个 WindowToken的窗口会被安排在一起,而且在其中定义的一些属性将会影响所有属于此WindowToken的窗口。这些都表明了属于同一个WindowToken的窗口之间的紧密联系。

  • WindowToken具有令牌的作用,是对应用组件的行为进行规范管理的一个手段。

WindowToken由应用组件或其管理者负责向WMS声明并持有。结合Android 12系统源码_窗口管理(三)WindowManagerService对窗口的管理过程我们可以知道,应用组件在需要新的窗口时,必须提供WindowToken以表明自己的身份,并且窗口的类型必须与所持有的WindowToken类型一致。

3、既然应用组件在创建一个窗口时必须指定一个有效的WindowToken才行,那么 WindowToken究竟该如何声明呢?来看一下WMS的addWindowToken方法。

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {

    @Override
    public void addWindowToken(@NonNull IBinder binder, int type, int displayId,
                               @Nullable Bundle options) {
        //需要声明Token的调用者拥有MANAGE_APP_TOKENS的权限,否则直接抛出异常
        if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
        }
        synchronized (mGlobalLock) {
            final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
            if (dc == null) {
                ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s"
                        + " for non-exiting displayId=%d", binder, displayId);
                return;
            }
            WindowToken token = dc.getWindowToken(binder);
            if (token != null) {
                ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s"
                        + " for already created window token: %s"
                        + " displayId=%d", binder, token, displayId);
                return;
            }
            if (type == TYPE_WALLPAPER) {//如果是壁纸类型,则创建壁纸窗口令牌
                new WallpaperWindowToken(this, binder, true, dc,
                        true /* ownerCanManageAppTokens */, options);
            } else {
                //创建通用的窗口令牌
                new WindowToken.Builder(this, binder, type)
                        .setDisplayContent(dc)
                        .setPersistOnEmpty(true)
                        .setOwnerCanManageAppTokens(true)
                        .setOptions(options)
                        .build();
            }
        }
    }

}

二、WindowState(窗口状态)

1、介绍

  • WindowState 是一个表示窗口状态的类。它用于跟踪窗口的属性和状态,以确保窗口正确地显示和布局。
  • WindowState 包含了窗口的各种属性,如位置、大小、可见性等。通过管理这些属性,系统可以管理窗口的显示和布局。
  • WindowState 还可以包含其他与窗口相关的信息,如焦点状态、输入事件处理等。
  • 与 WindowToken 不同,WindowState 更专注于管理窗口的状态和属性,而不是标识窗口中的特定视图层级。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值