在android.view.Windowclass中明确addFlags和setFlags

Make clear about addFlags and setFlags in android.view.Window class

我知道 setFlags 的作用是用新标志替换旧标志。 addFlags 正在附加更多标志。我只是很困惑,为什么我看到的 setFlags 方法中的参数通常是相同的? 例如:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
//or
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

看了 android.view.Window class 之后,我不清楚为什么他们必须做很多二元运算符(NOT、AND、OR)。这样做的目的是什么?

public void setFlags(int flags, int mask) {
        final WindowManager.LayoutParams attrs = getAttributes();
        attrs.flags = (attrs.flags & ~mask) | (flags & mask);
        mForcedWindowFlags |= mask;
        dispatchWindowAttributesChanged(attrs);
    }

还有一个问题,和

有什么区别
//argument is a flag
getWindow().addFlags(flag1);

//argument is the result of OR operator of 2 identical flags
getWindow().addFlags(flag1 | flag1);

//argument is the result of OR operator of 2 different flags
getWindow().addFlags(flag1 | flag2);

//argument is the result of AND operator of 2 identical flags
getWindow().addFlags(flag1 & flag1);

//argument is the result of AND operator of 2 different flags
getWindow().addFlags(flag1 & flag2);

如有任何帮助,我们将不胜感激。

二进制运算符是因为该字段是位字段。他们使用一个整数来保存很多设置,每个设置都分配给不同的位。然后,您使用二元运算将它们组合起来并正确设置位。这是一种常见的硬件技术,非常 space 高效。通常,您会通过在其上使用 OR 打开一个位(设置),并通过 AND 其逆运算将其删除。这两个操作都保持其余设置不变。

你永远不会看到 setFlags(FOO | FOO),因为它是多余的。所发生的只是 FOO 将被设置。您会看到 setFlags(FOO | BAR),它将同时设置 FOO 和 BAR。

当您看到 setFlags(FOO, FOO)- 第二个参数是掩码。它允许您同时打开和关闭字段,并且只有掩码中的位会发生变化。所以任何其他设置都将保持原样。数学基本上是 ((getFlags &~mask) | (value & mask))。如果您只想更改某些设置,并且想将它们全部打开,您会在两个值中看到相同的内容。 setFlags(x,x) 等同于 addFlags(x)

查看来源 Window.java

/**
 * Convenience function to set the flag bits as specified in flags, as
 * per {@link #setFlags}.
 * @param flags The flag bits to be set.
 * @see #setFlags
 * @see #clearFlags
 */
public void addFlags(int flags) {
    setFlags(flags, flags);
}

所以addFlagssetFlags一样但是更方便