一:前言
在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