Android提供了Invalidate方法實現介面重新整理,但是Invalidate不能直接線上程中呼叫,因為他是違背了單執行緒模型:Android UI操作並不是執行緒安全的,並且這些操作必須在UI執行緒中呼叫。
invalidate()是用來重新整理View的,必須是在UI執行緒中進行工作。比如在修改某個view的顯示時,呼叫invalidate()才能看到重新繪製的介面。invalidate()的呼叫是把之前的舊的view從主UI執行緒佇列中pop掉。 一個Android 程式預設情況下也只有一個程式,但一個程式下卻可以有許多個執行緒。
在這麼多執行緒當中,把主要是負責控制UI介面的顯示、更新和控制元件互動的執行緒稱為UI執行緒,由於onCreate()方法是由UI執行緒執行的,所以也可以把UI執行緒理解為主執行緒。其餘的執行緒可以理解為工作者執行緒。
invalidate()得在UI執行緒中被調動,在工作者執行緒中可以通過Handler來通知UI執行緒進行介面更新。
而postInvalidate()在工作者執行緒中被呼叫
利用invalidate()重新整理介面
例項化一個Handler物件,並重寫handleMessage方法呼叫invalidate()實現介面重新整理;而線上程中通過sendMessage傳送介面更新訊息。
1 // 在onCreate()中開啟執行緒 2 3 new Thread(new GameThread()).start();、 4 5 // 例項化一個handler 6 7 Handler myHandler = new Handler() { 8 // 接收到訊息後處理 9 public void handleMessage(Message msg) { 10 switch (msg.what) { 11 case Activity01.REFRESH: 12 mGameView.invalidate(); // 重新整理介面 13 break; 14 } 15 16 super.handleMessage(msg); 17 } 18 }; 19 20 class GameThread implements Runnable { 21 public void run() { 22 while (!Thread.currentThread().isInterrupted()) { 23 Message message = new Message(); 24 message.what = Activity01.REFRESH; 25 // 傳送訊息 26 Activity01.this.myHandler.sendMessage(message); 27 try { 28 Thread.sleep(100); 29 } catch (InterruptedException e) { 30 Thread.currentThread().interrupt(); 31 } 32 } 33 } 34 }
使用postInvalidate()重新整理介面
使用postInvalidate則比較簡單,不需要handler,直接線上程中呼叫postInvalidate即可。
1 class GameThread implements Runnable { 2 public void run() { 3 while (!Thread.currentThread().isInterrupted()) { 4 try { 5 Thread.sleep(100); 6 } catch (InterruptedException e) { 7 Thread.currentThread().interrupt(); 8 } 9 10 // 使用postInvalidate可以直接線上程中更新介面 11 mGameView.postInvalidate(); 12 } 13 } 14 }