2011-05-16 118 views
6

我正在實現一個SurfaceView子類,我在其中運行一個單獨的線程以繪製到SurfaceHolders畫布上。 我打電話給lockCanvas()之前和之後的時間,我從約70毫秒到100毫秒。 有沒有人可以指出爲什麼我會得到如此高的時間? 下面的代碼的相關部分:爲什麼lockCanvas()很慢?

public class TestView extends SurfaceView implements SurfaceHolder.Callback { 

.... 

boolean created; 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 

    mThread = new DrawingThread(mHolder, true); 
    mThread.onWindowResize(width, height); 
    mThread.start(); 
} 

public void surfaceCreated(SurfaceHolder holder) { 

    created = true; 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    created = false; 

} 
class DrawingThread extends Thread { 
public void run() { 
while(created) { 



      Canvas canvas = null; 
      try { 
          long t0 = System.currentTimeMillis(); 
      canvas = holder.lockCanvas(null); 
      long t1 = System.currentTimeMillis(); 
          Log.i(TAG, "Timing: " + (t1 - t0)); 
      } finally { 
       holder.unlockCanvasAndPost(canvas); 
      } 
} 

回答

1
+0

好的,謝謝。我已經閱讀過,並理解了這些概念。但我還沒有找到解決辦法。即使我刪除了'synchronized'塊(這是不推薦的),它並沒有幫助我。仍然那些高時間。 – kaneda 2011-05-16 12:44:29

4

你正在創建一個線程每面被改變的時間。你應該在surfaceCreated開始你的線程,並在surfaceDestroyed殺死它。 surfaceChanged適用於表面的尺寸發生變化時。

從SurfaceView。 surfaceCreated文檔:

這是在第一次創建曲面後立即調用的。這應該的實現啓動他們想要的任何呈現代碼。請注意,只有一個線程可以繪製成Surface,因此如果您的普通渲染將位於另一個線程中,則不應在此處繪製Surface。

多個線程可能讓你受到限制。從SurfaceHolder。 lockCanvas文檔:

如果調用此多次在表面還沒有準備好(Callback.surfaceCreated之前或之後Callback.surfaceDestroyed),您的通話將被以避免消耗CPU節流以緩慢的速度。

但是,我不相信這是唯一的問題。 surfaceChanged實際上被多次調用?

+0

當文檔聲明「只有一個線程可以繪製到Surface中......」這個語句是否應該以面值出現,或者他們說「......可以同時繪製成Surface *」。 – 2012-09-06 05:45:57

+1

我認爲應該從表面上看。即使不是,那麼你也必須處理序列化繪圖命令。 (這可能是爲什麼他們要求你在一個線程上提交它們。)根據http://stackoverflow.com/a/11258546/79125我是對的(但我們只是兩個在互聯網上的傢伙)。 – idbrii 2012-09-06 22:32:21

+0

哦。我非常喜歡一個很好的教程(該響應鏈接到)。謝謝。我希望我能給你兩個+ 1的那個=) – 2012-09-07 15:29:26

1

這與如何在android圖形框架中實際實現lockCanvas有關。

您應該已經知道lockCanvas會返回一個免費您將用於繪製的一​​段內存。通過免費,這意味着這種記憶不被用於組成,而不是用於顯示。在內部,簡單地說,SurfaceView由雙緩衝區備份,一個用於繪圖,一個用於組合/顯示。這個雙緩衝區由BufferQueque管理。 如果構圖/顯示比繪製慢,我們必須等到我們有空閒緩衝區可用。