Make clear about addFlags and setFlags in android.

2020-06-21 02:49发布

问题:

I know what setFlags does is replacing the old flags with the new ones. And addFlags is appending more flag. I'm just confused why are the arguments in setFlags method that I've seen usually the same? For example:

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

After taking a look at android.view.Window class, I'm not clear that why they must do many binary operators (NOT, AND, OR). What is the purpose of this?

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

One more question, what is the difference between

//argument is a flag
getWindow().addFlags(flag1);

and

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

and

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

and

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

and

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

Any help would be appreciated.

回答1:

The binary operators are because the field is a bitfield. They use a single integer to hold a lot of settings, and each settings are assigned to different bits. You then use binary operations to combine them and set the bits correctly. This is a common hardware technique, its very space efficient. Generally you'll turn on a bit (a setting) by using OR on it, and remove it by ANDing its inverse. Both of these operations leave the rest of the settings unchanged.

You would never see setFlags(FOO | FOO), because its redundant. All that happens is FOO would be set. You would see setFlags(FOO | BAR), which would set both FOO and BAR.

When you see setFlags(FOO, FOO)- the second parameter is a mask. It allows you to turn fields on and off at the same time, and only the bits in the mask will change. SO any other setting will be kept as it was. The math is basically ((getFlags &~mask) | (value & mask)). You'll see the same thing in both values if you only want to change certain settings, and you want to turn them all on. setFlags(x,x) is equivalent to addFlags(x)



回答2:

Look at the source of 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);
}

So addFlags is the same as setFlags but more convenient