android中Invalidate和postInvalidate的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android中Invalidate和postInvalidate的区别相关的知识,希望对你有一定的参考价值。
Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。
1,利用invalidate()刷新界面
实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中通过sendMessage发送界面更新消息。public class TestActivity extends Activity
private View view;
public class Handler handler = new Handler()
public void handleMessage(Message msg)
view.invalidate(); // 刷新界面
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread()
public void run()
handler.sendEmptyMessage();
.start();
2,使用postInvalidate()刷新界面 ,使用postInvalidate则比较简单,不需要handler,直接在线程中调用postInvalidate即可。
public class TestActivity extends Activityprivate View view;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread()
public void run()
view.postInvalidate();
.start();
两个方法都有重载函数,用于刷新指定区域的内容
public void invalidate(int l, int t, int r, int b) ;
public void invalidate(Rect dirty) ;
public void postInvalidate(int l, int t, int r, int b) ;
public void postInvalidate(Rect dirty) ;
此外postInvalidate还支持延迟刷新,
public void postInvalidateDelayed(long delayMilliseconds)
让视图在指定时间后刷新
参考技术A Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。
Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。
1,利用invalidate()刷新界面
实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中通过sendMessage发送界面更新消息。
// 在onCreate()中开启线程
new Thread(new GameThread()).start();、
// 实例化一个handler
Handler myHandler = new Handler()
// 接收到消息后处理
public void handleMessage(Message msg)
switch (msg.what)
case Activity01.REFRESH:
mGameView.invalidate(); // 刷新界面
break;
super.handleMessage(msg);
;
class GameThread implements Runnable
public void run()
while (!Thread.currentThread().isInterrupted())
Message message = new Message();
message.what = Activity01.REFRESH;
// 发送消息
Activity01.this.myHandler.sendMessage(message);
try
Thread.sleep(100);
catch (InterruptedException e)
Thread.currentThread().interrupt();
本回答被提问者和网友采纳
Android开发 View的UI刷新Invalidate和postInvalidate
Invalidate
正常刷新
/** * 使整个视图无效。如果视图可见, * @link #onDraw(android.graphics.Canvas) 调用此方法后将在后续的UI刷新里调用onDraw(android.graphics.Canvas)方法 * <p> * 必须从UI线程调用此方法。要从非UI线程调用,请调用@link #postInvalidate().*/ public void invalidate() invalidate(true); /** * This is where the invalidate() work actually happens. A full invalidate() * causes the drawing cache to be invalidated, but this function can be * called with invalidateCache set to false to skip that invalidation step * for cases that do not need it (for example, a component that remains at * the same dimensions with the same content). * * @param invalidateCache Whether the drawing cache for this view should be * invalidated as well. This is usually true for a full * invalidate, but may be set to false if the View‘s contents or * dimensions have not changed. * @hide */ public void invalidate(boolean invalidateCache) invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
一些解释
1.首先invalidate() 也是调用 invalidate(boolean invalidateCache) 这个方法的,只有设置为true时才会让这个View刷新
2.上面的注释已经说了invalidate()的刷新是必需在UI线程的
设置布局位置,重新调整View的刷新位置
/** * Mark the area defined by dirty as needing to be drawn. If the view is * visible, @link #onDraw(android.graphics.Canvas) will be called at some * point in the future. * <p> * This must be called from a UI thread. To call from a non-UI thread, call * @link #postInvalidate(). * <p> * <b>WARNING:</b> In API 19 and below, this method may be destructive to * @code dirty. * * @param dirty the rectangle representing the bounds of the dirty region * * @deprecated The switch to hardware accelerated rendering in API 14 reduced * the importance of the dirty rectangle. In API 21 the given rectangle is * ignored entirely in favor of an internally-calculated area instead. * Because of this, clients are encouraged to just call @link #invalidate(). */ @Deprecated public void invalidate(Rect dirty) final int scrollX = mScrollX; final int scrollY = mScrollY; invalidateInternal(dirty.left - scrollX, dirty.top - scrollY, dirty.right - scrollX, dirty.bottom - scrollY, true, false); /** * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The * coordinates of the dirty rect are relative to the view. If the view is * visible, @link #onDraw(android.graphics.Canvas) will be called at some * point in the future. * <p> * This must be called from a UI thread. To call from a non-UI thread, call * @link #postInvalidate(). * * @param l the left position of the dirty region * @param t the top position of the dirty region * @param r the right position of the dirty region * @param b the bottom position of the dirty region * * @deprecated The switch to hardware accelerated rendering in API 14 reduced * the importance of the dirty rectangle. In API 21 the given rectangle is * ignored entirely in favor of an internally-calculated area instead. * Because of this, clients are encouraged to just call @link #invalidate(). */ @Deprecated public void invalidate(int l, int t, int r, int b) final int scrollX = mScrollX; final int scrollY = mScrollY; invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
postInvalidate
这个方法可以非UI线程中调用
正常刷新
/** * <p>导致在事件循环的后续循环中发生无效。使用此选项使非UI线程中的View无效</p> * * <p>仅当此视图附加到窗口时,才能从UI线程*外部调用此方法。</p> * * @see #invalidate() * @see #postInvalidateDelayed(long) */ public void postInvalidate() postInvalidateDelayed(0);
改变位置后刷新
/** * <p>Cause an invalidate of the specified area to happen on a subsequent cycle * through the event loop. Use this to invalidate the View from a non-UI thread.</p> * * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * * @param left The left coordinate of the rectangle to invalidate. * @param top The top coordinate of the rectangle to invalidate. * @param right The right coordinate of the rectangle to invalidate. * @param bottom The bottom coordinate of the rectangle to invalidate. * * @see #invalidate(int, int, int, int) * @see #invalidate(Rect) * @see #postInvalidateDelayed(long, int, int, int, int) */ public void postInvalidate(int left, int top, int right, int bottom) postInvalidateDelayed(0, left, top, right, bottom);
延迟刷新
/** * <p>导致在事件*循环的后续循环中发生无效。等待指定的时间。</p> * * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * * @param delayMilliseconds the duration in milliseconds to delay the * invalidation by * * @see #invalidate() * @see #postInvalidate() */ 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 final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
改变位置,并且延迟刷新
/** * <p>Cause an invalidate of the specified area to happen on a subsequent cycle * through the event loop. Waits for the specified amount of time.</p> * * <p>This method can be invoked from outside of the UI thread * only when this View is attached to a window.</p> * * @param delayMilliseconds the duration in milliseconds to delay the * invalidation by * @param left The left coordinate of the rectangle to invalidate. * @param top The top coordinate of the rectangle to invalidate. * @param right The right coordinate of the rectangle to invalidate. * @param bottom The bottom coordinate of the rectangle to invalidate. * * @see #invalidate(int, int, int, int) * @see #invalidate(Rect) * @see #postInvalidate(int, int, int, int) */ public void postInvalidateDelayed(long delayMilliseconds, int left, int top, int right, int bottom) // We try only with the AttachInfo because there‘s no point in invalidating // if we are not attached to our window final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain(); info.target = this; info.left = left; info.top = top; info.right = right; info.bottom = bottom; attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
end
以上是关于android中Invalidate和postInvalidate的区别的主要内容,如果未能解决你的问题,请参考以下文章
android中Invalidate和postInvalidate的差别
android中Invalidate和postInvalidate的区别
android中Invalidate和postInvalidate的区别
invalidate和postInvalidate 的区别及使用