您的位置:首页 > 移动开发 > Android开发

对Android源码中常见的一些flag的运算的理解

2015-12-03 17:38 761 查看
在Android源码中,包括一些比较规范的源码中,通常会出现flag(我理解我标志位)。

可以这么认为:

    a&~b:   清除标志位b;
    a|b:       添加标志位b;
    a&b:     取出标志位b;
      a^b:    取出a与b的不同部分;

例如在View的setFlags方法中有如下代码:

void setFlags(int flags, int mask) {
int old = mViewFlags;//将标记赋值给old
mViewFlags = (mViewFlags & ~mask) | (flags & mask);//mViewFlags清除mask后添加从flags中取出的mask标志

int changed = mViewFlags ^ old;//取出新旧标记的不同部分。
if (changed == 0) {
return;
}
int privateFlags = mPrivateFlags;

/* Check if the FOCUSABLE bit has changed */
if (((changed & FOCUSABLE_MASK) != 0) &&
((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
if (((old & FOCUSABLE_MASK) == FOCUSABLE)
&& ((privateFlags & PFLAG_FOCUSED) != 0)) {
/* Give up focus if we are no longer focusable */
clearFocus();
} else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
&& ((privateFlags & PFLAG_FOCUSED) == 0)) {
/*
* Tell the view system that we are now available to take focus
* if no one else already has it.
*/
if (mParent != null) mParent.focusableViewAvailable(this);
}
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
notifyAccessibilityStateChanged();
}
}

if ((flags & VISIBILITY_MASK) == VISIBLE) {
if ((changed & VISIBILITY_MASK) != 0) {
/*
* If this view is becoming visible, invalidate it in case it changed while
* it was not visible. Marking it drawn ensures that the invalidation will
* go through.
*/
mPrivateFlags |= PFLAG_DRAWN;
invalidate(true);

needGlobalAttributesUpdate(true);

// a view becoming visible is worth notifying the parent
// about in case nothing has focus.  even if this specific view
// isn't focusable, it may contain something that is, so let
// the root view try to give this focus if nothing else does.
if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
mParent.focusableViewAvailable(this);
}
}
}

/* Check if the GONE bit has changed */
if ((changed & GONE) != 0) {
needGlobalAttributesUpdate(false);
requestLayout();

if (((mViewFlags & VISIBILITY_MASK) == GONE)) {
if (hasFocus()) clearFocus();
clearAccessibilityFocus();
destroyDrawingCache();
if (mParent instanceof View) {
// GONE views noop invalidation, so invalidate the parent
((View) mParent).invalidate(true);
}
// Mark the view drawn to ensure that it gets invalidated properly the next
// time it is visible and gets invalidated
mPrivateFlags |= PFLAG_DRAWN;
}
if (mAttachInfo != null) {
mAttachInfo.mViewVisibilityChanged = true;
}
}

/* Check if the VISIBLE bit has changed */
if ((changed & INVISIBLE) != 0) {
needGlobalAttributesUpdate(false);
/*
* If this view is becoming invisible, set the DRAWN flag so that
* the next invalidate() will not be skipped.
*/
mPrivateFlags |= PFLAG_DRAWN;

if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) {
// root view becoming invisible shouldn't clear focus and accessibility focus
if (getRootView() != this) {
clearFocus();
clearAccessibilityFocus();
}
}
if (mAttachInfo != null) {
mAttachInfo.mViewVisibilityChanged = true;
}
}

if ((changed & VISIBILITY_MASK) != 0) {
if (mParent instanceof ViewGroup) {
((ViewGroup) mParent).onChildVisibilityChanged(this,
(changed & VISIBILITY_MASK), (flags & VISIBILITY_MASK));
((View) mParent).invalidate(true);
} else if (mParent != null) {
mParent.invalidateChild(this, null);
}
dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));
}

if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
destroyDrawingCache();
}

if ((changed & DRAWING_CACHE_ENABLED) != 0) {
destroyDrawingCache();
mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
invalidateParentCaches();
}

if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
destroyDrawingCache();
mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}

if ((changed & DRAW_MASK) != 0) {
if ((mViewFlags & WILL_NOT_DRAW) != 0) {
if (mBackground != null) {
mPrivateFlags &= ~PFLAG_SKIP_DRAW;
mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
} else {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
} else {
mPrivateFlags &= ~PFLAG_SKIP_DRAW;
}
requestLayout();
invalidate(true);
}

if ((changed & KEEP_SCREEN_ON) != 0) {
if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
mParent.recomputeViewAttributes(this);
}
}

if (AccessibilityManager.getInstance(mContext).isEnabled()
&& ((changed & FOCUSABLE) != 0 || (changed & CLICKABLE) != 0
|| (changed & LONG_CLICKABLE) != 0 || (changed & ENABLED) != 0)) {
notifyAccessibilityStateChanged();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 源码 flag