invalidate()是用來刷新屏幕更新View的,必須是在主線程中進行工作.因為它屬于更新UI. 比如在修改某個View的顯示時,調用invalidate()才能看到重新繪制的界面,invalidate()的調用就是把之前的舊View中從主UI線程隊列中pop掉.
對于屏幕刷新有以下3種情況:
1. 不使用多線程和雙緩沖
這種情況最簡單.一般只是希望在View發(fā)生改變時對UI進行重繪. 只需要在Activity中顯示的調用View對象中的invalidate()方法即可.系統(tǒng)會自動調用View的onDraw()方法.
2. 使用多線程但不使用雙緩沖
這種情況,需要開啟子線程,開啟的子線程不好訪問View對象.強行訪問的話報:Android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.
其意思就是子線程不能更新Ui.這個時候.需要創(chuàng)建一個繼承了android.os.Handler的子類,并重寫handleMessage(Message msg)方法. android.os.Handler是能發(fā)送和處理消息的,你需要在Activity中發(fā)出更新UI的消息,然后在你的Handler(可以使用匿名內部類)中處理消息(因為匿名內部類可以訪問父類變量,你可以直接使用View對象調用View的invalidate()方法.).也就是說:在新線程中創(chuàng)建并發(fā)送一個Message,然后再主線程中捕獲,處理該消息.
3. 使用雙線程和雙緩沖
Android中SurfaceView是View的子類,它同時也實現(xiàn)了雙緩沖, 你可以定義一個它的子類并實現(xiàn)SurfaceHandler.Callback接口.由于實現(xiàn)SurfaceHolder.Callback接口,新線程就不需要android.os.Handler來幫忙了.SurfaceHolder.Callback中l(wèi)ockCanvas()方法可以鎖定畫布.繪制完新的圖像后調用unlockCanvasAndPost(canvas)解鎖(顯示).還是還是比較方便的.