Android flag理解

轉載地址:https://www.cnblogs.com/universal/p/5425183.html

以下紅字爲小弟自己的一些理解。

Flag理解

    在閱讀源碼的時候經常發現有一些標誌屬性使用一些位操作來判斷是否具有該標誌,增加標誌或者去除標誌。

比如View.java中的

/**
     * This view does not want keystrokes. Use with     TAKES_FOCUS_MASK when
     * calling setFlags.
     */
    private static final int NOT_FOCUSABLE = 0x00000000;

    /**
     * This view wants keystrokes. Use with TAKES_FOCUS_MASK     when calling
     * setFlags.
     */
    private static final int FOCUSABLE = 0x00000001;
爲什麼要使用16進制呢?爲何不使用十進制0,1,2...?原因是因爲這樣就可以方便的用位運算來表示共同具有某些屬性或者直接判斷是否具有某個屬性。

上面這句話我們稍微來分析一下。拿文件的權限來分析一下,我們知道文件有三個權限:讀,寫,執行。分別用4 , 2 , 1來表示,這樣一來就可以很快速的知道文件所有的權限,比如5表示可讀可執行兩個權限,7表示可讀可寫可執行權限。

如果把上面的2進制換成10進制呢?結果就會變得很尷尬。假如上面三個權限分別用1 , 2 , 3表示,3這個就會很尷尬,因爲我們不知道這個值表示的是可讀可寫兩個權限還是僅僅一個執行權限。


Android源碼中主要針對FLAG的運算有三種

①. 增加屬性 "|"
如果需要向flag變量中增加某個FLAG,使用"|"運算符
    flag |= XXX_FLAG;
原因: 如果flag變量沒有XXX_FLAG,則 | 完後flag對應的位爲1,如果有XXX_FLAG,則 | 完後值不會變對應位還是1. 

②. 包含屬性 "&"
  如果需要判斷flag變量中是否包含XXX_FLAG,使用"&"運算符
  flag & XXX_FLAG  !=  0 或者 flag & XXX_FLAG = XXX_FLAG

原因: 如果flag變量裏包含XXX_FLAG,則&完後flag變量對應的位爲1,因爲XXX_FLAG的定義保證了只有一位非0,其他位都爲0,所以如果是包含的話&運算後值不爲0,值爲此XXX_FLAG的值,不包含的話值爲0. 


③.取消屬性 "&~"
  如果需要取消flag變量的XXX_FLAG, 使用 "&~". 
  flag &= ~XXX_FLAG;
原因: 先對XXX_FLAG進行取反 則XXX_FLAG原來非0的那一位變爲0,則使用&運算符後flag變量非0的那一位變爲0,則意味着flag變量不包含XXX_FLAG. 

這樣做的好處就是可以用一個值表示多種狀態。假如這裏有四種狀態:是否可點擊,是否獲取焦點。我們只需用flag標記 : 0x1,0x2,0x4,0x8 , 然後保存到一個值裏面就行,用以上的運算符就能快速的增加刪除以及判斷屬性了。

使用位移<<操作符

static final int VIEW_STATE_WINDOW_FOCUSED = 1;
static final int VIEW_STATE_SELECTED = 1 << 1;
static final int VIEW_STATE_FOCUSED = 1 << 2;
static final int VIEW_STATE_ENABLED = 1 << 3;
static final int VIEW_STATE_ACTIVATED= 1<< 5;

和

static final int VIEW_STATE_WINDOW_FOCUSED = 0x00000001;
static final int VIEW_STATE_SELECTED = 0x00000002;
static final int VIEW_STATE_FOCUSED = 0x00000004;
static final int VIEW_STATE_ENABLED = 0x00000008;
static final int VIEW_STATE_ACTIVATED= 0x00000010;
兩種寫法是等價的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章