android-invalidate和postInvalidate 的區別及使用

desaco發表於2016-01-16

> android中實現view的更新有兩組方法,一組是invalidate,另一組是postInvalidate,其中前者是在UI執行緒自身中使用,而後者在非UI執行緒中使用。 
    Android提供了Invalidate方法實現介面重新整理,但是Invalidate不能直接線上程中呼叫,因為他是違背了單執行緒模型:Android UI操作並不是執行緒安全的,並且這些操作必須在UI執行緒中呼叫。 
  Android程式中可以使用的介面重新整理方法有兩種,分別是利用Handler和利用postInvalidate()來實現線上程中重新整理介面。 
利用invalidate()重新整理介面
例項化一個Handler物件,並重寫handleMessage方法呼叫invalidate()實現介面重新整理;而線上程中通過sendMessage傳送介面更新訊息。
> 使用invalidate() 重新整理介面
 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();  
                }  
            }  
        }  
    }  
使用postInvalidate()重新整理介面 
使用postInvalidate則比較簡單,不需要handler,直接線上程中呼叫postInvalidate即可。 
class GameThread implements Runnable { 
   public void run() { 
while (!Thread.currentThread().isInterrupted()) { 
try { 
Thread.sleep(100); 
} catch (InterruptedException e) { 
Thread.currentThread().interrupt(); 
     } 
      // 使用postInvalidate可以直接線上程中更新介面 
      mGameView.postInvalidate(); 
     } 
  } 
}

View 類中postInvalidate()方法原始碼如下,可見它也是用到了handler的:

  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       

if (mAttachInfo != null) {          

 Message msg = Message.obtain();         

 msg.what = AttachInfo.INVALIDATE_MSG;          

 msg.obj = this;           m

AttachInfo.mHandler.sendMessageDelayed(msg, delayMilliseconds);

       } }

...除了onCreate()是執行在UI執行緒上的,其實其他大部分方法都是執行在UI執行緒上的,其實其實只要你沒有開啟新的執行緒,你的程式碼基本上都執行在UI執行緒上。

相關文章