這裏說的是在繪圖中二者的區別:java
1View在繪圖中,重寫onDraw(Canvas canvas)方法,經過invaldate()和pastInvalidate()兩個方法進行從新繪製畫布;canvas
invalidate()不能再本身建立的線程中循環調用;ide
postInvalidate()能夠在本身建立的線程中循環調用執行。若是不在當前View 建立線程循環重繪畫布的話,這兩種重繪畫布的函數就沒什麼區別了,均可以用。函數
public class MyView extends View { private float x; private float y; public MyView(Context context) { super(context); } //須要繪製圖像時調用 @Override protected void onDraw(Canvas canvas) { Paint mPaint = new Paint(); mPaint.setColor(Color.BLUE); canvas.drawLine(0, 0, x, y, mPaint); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { x = event.getX(); y = event.getY(); //重繪畫布 invalidate(); // postInvalidate(); return true; } }
2,surfaceView繼承自viewpost
在使用surfaceView時,你會發現複寫父類的onDraw(Canvas canvas)方法並不會執行。緣由是在SurfaceView中,咱們並不會直接跟他打交道,而是經過SurfaceHolder來控制。使用SurfaceHolder的lockCanvas()函數來獲取到SurfaceView的Canvas對象,再經過Canvas上繪製內容來修改SurfaceView中的數據this
public class MySurfaceView extends SurfaceView implements Callback, Runnable { private SurfaceHolder sfh; private Paint paint; private Canvas canvas; private Thread th; private boolean flag; private int textX; private int textY; public MySurfaceView(Context context) { super(context); sfh = this.getHolder(); sfh.addCallback(this); paint = new Paint(); paint.setColor(Color.WHITE); } @Override public void surfaceCreated(SurfaceHolder holder) { flag = true; th = new Thread(this); th.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { flag = false; } @Override public boolean onTouchEvent(MotionEvent event) { textX = (int) event.getX(); textY = (int) event.getY(); return true; } public void myDraw() { // 獲取一個加鎖的畫布,爲了防止surfaceview在繪製過程當中被修改,銷燬等情況 Paint blackPaint = new Paint(); blackPaint.setColor(Color.BLACK); try { canvas = sfh.lockCanvas(); if (canvas != null) { canvas.drawRect(0, 0, getWidth(), getHeight(), blackPaint);// 刷屏1 // canvas.drawColor(Color.BLACK);//刷屏2 // canvas.drawRGB(0, 0, 0);//刷屏3 canvas.drawText("game", textX, textY, paint); } } catch (Exception e) { e.printStackTrace(); }finally{ if (canvas != null) { // 解鎖畫布和提交 sfh.unlockCanvasAndPost(canvas); } } } /** * 遊戲邏輯 */ private void logic() { } @Override public void run() { while (flag) { long start = System.currentTimeMillis(); myDraw(); logic(); long end = System.currentTimeMillis(); try { if (end - start < 50) { Thread.sleep(50 - (end - start)); } } catch (InterruptedException e) { e.printStackTrace(); } } } }
他們兩個更新畫布的區別:線程
在View視圖中對於畫布的從新繪製,是經過調用View 提供的postInvalidate()與inValidate()這兩個函數來執行的,也就是說畫布是由系統主UI進行更新。那麼當系統主UI線程被繪製函數阻塞,這樣一來則會引起沒法響應按鍵,觸屏等消息的問題;code
SurfaceView視圖中對於畫布的重繪是由一個新的單獨線程去執行處理,因此不會出現因主UI線程阻塞而致使沒法響應按鍵,觸屏信息等問題。orm
surfaceview 有雙緩衝機制,而view 沒有
對象