Refreshing mechanism of Android View

Source: Internet
Author: User

Today, I learned how to refresh the android VIEW. Previously, I thought that I would call the refresh function when calling the refresh of the VIEW. Today I learned about the refresh mechanism of the view, but I learned a lot.

 

I think that I want to read more android source code. In fact, many messaging and other mechanisms are obtained by reading the android source code. If you have nothing to do with it, let's go and check the source code ~

 

Well, the key sentence is:

 

In the Layout System of Android, the parent View is responsible for refreshing and displaying the child View. When the child View needs to be refreshed, the parent View is notified to complete the process.

 

The steps are as follows:

1. Call the invalidate () of the subview ()

2. Jump to the invalidateChild function area on the previous layer.

3. Refresh the invalidateChildInParent function at a time.

4. I am not clear about the specific subsequent refresh operations. Calling invalidate ended in invalidateChild in the code, so it is a little unclear, could you please introduce me .....? Thank you ..

 

Let me read the source code:

First, in the View class:

 

/**
* Invalidate the whole view. If the view is visible, {@ link # onDraw} will
* Be called at some point in the future. This must be called from
* UI thread. To call from a non-UI thread, call {@ link # postInvalidate ()}.
*/
Public void invalidate (){
If (ViewDebug. TRACE_HIERARCHY ){
ViewDebug. trace (this, ViewDebug. HierarchyTraceType. INVALIDATE );
}

If (mPrivateFlags & (DRAWN | HAS_BOUNDS) = (DRAWN | HAS_BOUNDS )){
MPrivateFlags & = ~ DRAWN &~ DRAWING_CACHE_VALID;

Final ViewParent p = mParent; // get the object of the parent Class View
Final AttachInfo ai = mAttachInfo; // obtain a match
If (p! = Null & ai! = Null ){
Final Rect r = ai. mTmpInvalRect;
R. set (0, 0, mRight-mLeft, mBottom-mTop); // set the size of the View. In fact, the size is not set.

// Don't call invalidate -- we don't want to internally scroll
// Our own bounds
P. invalidateChild (this, r); // call the refresh function of the parent class
}
}
}

 

 

Next we will go to the Viewgroup object:

In invalidate, The invalidateChild of the parent View is called. This is a process of back up from the beginning. The parent View of each layer intersection its display area with the incoming Rect refresh.

/**
* Don't call or override this method. It is used for the implementation
* The view hierarchy.
*/
Public final void invalidateChild (View child, final Rect dirty ){
If (ViewDebug. TRACE_HIERARCHY ){
ViewDebug. trace (this, ViewDebug. HierarchyTraceType. INVALIDATE_CHILD );
}

ViewParent parent = this;
Final AttachInfo attachInfo = mAttachInfo;
If (attachInfo! = Null ){
Final int [] location = attachInfo. mInvalidateChildLocation;

// Refresh the position of the sub-View
Location [CHILD_LEFT_INDEX] = child. mLeft;
Location [CHILD_TOP_INDEX] = child. mTop;

// If the child is drawing an animation, we want to copy this flag
// Ourselves and the parent to make sure the invalidate request goes
// Through
Final boolean drawAnimation = (child. mPrivateFlags & DRAW_ANIMATION) = DRAW_ANIMATION;

// Check whether the child that requests the invalidate is fully opaque
Final boolean isOpaque = child. isOpaque ()&&! DrawAnimation &&
Child. getAnimation ()! = Null;
// Mark the child as dirty, using the appropriate flag
// Make sure we do not set both flags at the same time
Final int opaqueFlag = isOpaque? DIRTY_OPAQUE: DIRTY;
Do {
View view = null;
If (parent instanceof View ){
View = (View) parent;
}

If (drawAnimation ){
If (view! = Null ){
View. mPrivateFlags | = DRAW_ANIMATION;
} Else if (parent instanceof ViewRoot ){
(ViewRoot) parent). mIsAnimating = true;
}
}

// If the parent is dirty opaque or not dirty, mark it dirty with the opaque
// Flag coming from the child that initiated the invalidate
If (view! = Null & (view. mPrivateFlags & DIRTY_MASK )! = DIRTY ){
View. mPrivateFlags = (view. mPrivateFlags &~ DIRTY_MASK) | opaqueFlag;
}
Parent = parent. invalidateChildInParent (location, dirty );
} While (parent! = Null );
}

 

/**
* Don't call or override this method. It is used for the implementation
* The view hierarchy.
*
* This implementation returns null if this ViewGroup does not have a parent,
* If this ViewGroup is already fully invalidated or if the dirty rectangle
* Does not intersect with this ViewGroup's bounds.
*/Www.2cto.com
Public ViewParent invalidateChildInParent (final int [] location, final Rect dirty ){
If (ViewDebug. TRACE_HIERARCHY ){
ViewDebug. trace (this, ViewDebug. HierarchyTraceType. INVALIDATE_CHILD_IN_PARENT );
}

If (mPrivateFlags & DRAWN) = DRAWN ){
If (mGroupFlags & (FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE ))! =
FLAG_OPTIMIZE_INVALIDATE ){

// The Position of the parent class, offset refresh Area
Dirty. offset (location [CHILD_LEFT_INDEX]-mScrollX,
Location [CHILD_TOP_INDEX]-mScrollY );

Final int left = mLeft;
Final int top = mTop;

If (dirty. intersect (0, 0, mRight-left, mBottom-top) |
(MPrivateFlags & DRAW_ANIMATION) = DRAW_ANIMATION ){
MPrivateFlags & = ~ DRAWING_CACHE_VALID;
Location [CHILD_LEFT_INDEX] = left;
Location [CHILD_TOP_INDEX] = top;
Return mParent;
}
} Else {
MPrivateFlags & = ~ DRAWN &~ DRAWING_CACHE_VALID;
Location [CHILD_LEFT_INDEX] = mLeft;
Location [CHILD_TOP_INDEX] = mTop;
Dirty. set (0, 0, mRight-location [CHILD_LEFT_INDEX],
MBottom-location [CHILD_TOP_INDEX]);
Return mParent;
}
}
Return null;
}

 

In addition:

The Invalidate () method cannot be placed in the thread, so you need to put the Invalidate () method in Handler. In MyThread, you only need to send a Message to handler within the specified time. When Handler receives the Message, it calls the Invalidate () method.

The postInvalidate () method can be put in the thread for processing without Handler.

The new thread MyThre can be started in OnCreate () or OnStart.

Both the Invalidate () method and postInvalidate () method can be called in the main thread to refresh the view.

The Invalidate () method is described in the SDK as follows: Invalidate the whole view. if the view is visible, onDraw (Canvas) will be called at some point in the future. this must be called from a UI thread. to call from a non-UI thread, call postInvalidate (). when Invalidate () is called, The OnDraw () of View is called, and Invalidate () must be called in the UI thread, if you update a view in a new thread, call postInvalidate ().


 

Author: ljz2009y

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.