View 中 flag标记,掩码位运算

一:前言

在Android源码中, 发现了大量使用使用位运算 & | << ~, 有一次我看到view.setClickable(true)方法时, 发现它竟然是这样的(如下代码), 当时我就傻眼了,好端端的一个boolean值, 保存就完事了, 为啥要搞得这么复杂?

    public void setClickable(boolean clickable) {
        setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
    }

二. 使用掩码位运算 保存数据的本质

本质: 利用二进制位, 去保存一些值.
例如:boolean值在jvm中占了4个字节, 也就是32位,如下图:
如果使用二进制位,每位用0/1去保存一个布尔值, 那4个字节就可以保存32个布尔值, 从而节省内存.


三. View 中 flag标记如何保存:

例如:初始值如下

flags = 0  //初始值

int a = 0x1 << 1;  ---> 0001    ---> 2^0 = 1
int b = 0x1 << 2;  ---> 0010    ---> 2^1 = 2
int c = 0x1 << 3;  ---> 0100    ---> 2^2 = 4
int d = 0x1 << 4;  ---> 1000    ---> 2^3 = 8

以a为例,计算过程如下图:

结论如下:


//添加标记
flags |= a  --->  添加标记 a
flags |= b  --->  添加标记 b


//移除标记
flags &= ~a  --->  移除标记 a
flags &= ~b  --->  移除标记 b


//取出标记
flags & a  --->  取出标记 a   ----> 取出结果:a本身    或者 0
flags & b  --->  取出标记 b

如下图, 看flag值 , 就可以得出存了哪些值


四. 运算规则

1 & 任何数都是那个数本身
0 & 任何数都是 0
0 | 任何数都是那个数本身
1 | 任何数都是 1
五. 在ViewGoup的标记位
int mGroupFlags;  --->默认为0



int FLAG_CLIP_CHILDREN = 0x1;     ---> 2^0 = 1

int FLAG_CLIP_TO_PADDING = 0x2;      ---> 2^1 = 2

int FLAG_INVALIDATE_REQUIRED  = 0x4;     ---> 2^2 = 4

int FLAG_RUN_ANIMATION = 0x8;      ---> 2^3 = 8

int FLAG_ANIMATION_DONE = 0x10;     ---> 2^4 = 16

int FLAG_PADDING_NOT_NULL = 0x20;     ---> 2^5 = 32

int FLAG_ANIMATION_CACHE = 0x40;     ---> 2^6 = 64

int FLAG_OPTIMIZE_INVALIDATE = 0x80;      ---> 2^7 = 128

int FLAG_CLEAR_TRANSFORMATION = 0x100;      ---> 2^7 = 256

int FLAG_NOTIFY_ANIMATION_LISTENER = 0x200;     ---> 2^7 = 512

int FLAG_USE_CHILD_DRAWING_ORDER = 0x400;     ---> 2^8 = 1024
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章