Android提供了Invalidate方法實現界面刷新,可是Invalidate不能直接在線程中調用,由於他是違背了單線程模型:安全
Android UI操做並非線程安全的,而且這些操做必須在UI線程中調用。 多線程
invalidate()是用來刷新View的,必須是在UI線程中進行工做。好比在修改某個view的顯示時,調用invalidate()才能post
看到從新繪製的界面。invalidate()的調用是把以前的舊的view從主UI線程隊列中pop掉。this
Android 程序默認狀況下也只有一個進程,但一個進程下卻能夠有許多個線程。在這麼多線程當中,把主要是負責控spa
制UI界面的顯示、更新和控件交互的線程稱爲UI線程,因爲onCreate()方法是由UI線程執行的,因此也能夠把UI線程理解線程
爲主線程。其他的線程能夠理解爲工做者線程。invalidate()得在UI線程中被調動,在工做者線程中能夠經過Handler來通code
知UI線程進行界面更新。而postInvalidate()在工做者線程中被調用。對象
1、利用invalidate()刷新界面blog
實例化一個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 }
2、使用postInvalidate()刷新界面
1 使用postInvalidate則比較簡單,不須要handler,直接在工做線程中調用postInvalidate便可。 2 3 class GameThread implements Runnable { 4 public void run() { 5 while (!Thread.currentThread().isInterrupted()) { 6 try { 7 Thread.sleep(100); 8 } catch (InterruptedException e) { 9 Thread.currentThread().interrupt(); 10 } 11 12 // 使用postInvalidate能夠直接在工做線程中更新界面 13 mGameView.postInvalidate(); 14 } 15 } 16 }