View Source Code:
Postinvalidate uses handler to send messages, that is, it can be used in a non-UI thread, while invalidate directly modifies the layout, so it can only be used in the UI thread.
Public void invalidate (){
Invalidate (true );
}
Void invalidate (Boolean invalidatecache ){
If (viewdebug. trace_hierarchy ){
Viewdebug. Trace (this, viewdebug. hierarchytracetype. invalidate );
}
If (skipinvalidate ()){
Return;
}
If (mprivateflags & (drawn | has_bounds) = (drawn | has_bounds) |
(Invalidatecache & (mprivateflags & drawing_cache_valid) = drawing_cache_valid) |
(Mprivateflags & invalidated )! = Invalidated | isopaque ()! = Mlastisopaque ){
Mlastisopaque = isopaque ();
Mprivateflags & = ~ Drawn;
Mprivateflags | = dirty;
If (invalidatecache ){
Mprivateflags | = invalidated;
Mprivateflags & = ~ Drawing_cache_valid;
}
Final attachinfo AI = mattachinfo;
Final viewparent P = mparent;
// Noinspection pointlessbooleanexpression, constantconditions
If (! Hardwarerenderer. render_dirty_regions ){
If (P! = NULL & Ai! = NULL & ai. mhardwareaccelerated ){
// Fast-track for GL-enabled applications; just invalidate the whole hierarchy
// With a null dirty rect, which tells the viewancestor to redraw everything
P. invalidatechild (this, null );
Return;
}
}
If (P! = NULL & Ai! = NULL ){
Final rect r = ai. mtmpinvalrect;
R. Set (0, 0, mright-mleft, mbottom-MTop );
// Don't call invalidate -- we don't want to internally scroll
// Our own Bounds
P. invalidatechild (this, R );
}
}
}
Public void postinvalidate (){
Postinvalidatedelayed (0 );
}
Public void postinvalidatedelayed (long delaymilliseconds ){
// We try only with the attachinfo because there's no point in invalidating
// If we are not attached to our window
Attachinfo = mattachinfo;
If (attachinfo! = NULL ){
Message MSG = message. Obtain ();
MSG. What = attachinfo. invalidate_msg;
MSG. OBJ = this;
Attachinfo. mhandler. sendmessagedelayed (MSG, delaymilliseconds );
}
}
Zookeeper