2012-12-10 74 views
3

我有一個手動繪製的自定義視圖。我將東西繪製成位圖,然後在onDraw()中使用該位圖。我意識到,如果我啓用繪圖緩存,我可以使用該緩存而不是創建自己的位圖。這大部分工作。從onDraw()調用getDrawingCache()時StackOverflowError()

目前我的onDraw方法是這樣的:

protected void onDraw(Canvas canvas) { 
    canvas.drawBitmap(getDrawingCache(), 0, 0, null); 
} 

這正常工作在我試過模擬器。不過,我收到StackOverflowError的崩潰報告。報告看起來像這樣:

java.lang.StackOverflowError 
at android.view.View.getDrawingCache(View.java:10481) 
at android.view.View.getDrawingCache(View.java:10446) 
at com.aragaer.jtt.JTTClockView.onDraw(JTTClockView.java:162) 
at android.view.View.draw(View.java:10983) 
at android.view.View.buildDrawingCache(View.java:10700) 
at android.view.View.getDrawingCache(View.java:10481) 
at android.view.View.getDrawingCache(View.java:10446) 
and so on... 

我看了一下android源代碼,其實buildDrawingCache調用draw()。這將解釋循環。但buildDrawingCache()應該在第二次調用時立即返回。

雖然沒有設置PFLAG_DRAWING_CACHE_VALID(source),但這種情況不會發生。並且該標誌僅在視圖附加到父級時才設置,IS硬件加速且層類型爲LAYER_TYPE_NONE(source again)。

問題是 - 是否可以顯式設置圖層類型爲非 - 無或我應該使用其他方法?如果是,我應該選擇哪種類型?

+0

如果您的方法取決於其他類的無證內部狀態,這並不好。它很可能會破解更新的版本,並可能會在許多其他版本中被破解,而這些版本您還沒有測試過。 (並且可以禁用硬件加速) – zapl

回答

5

getDrawingCache()從來沒有打算被視圖本身使用。它由父母管理。 View硬件加速時未設置標誌的原因是因爲「繪圖緩存」與硬件加速具有不同的含義。它用於控制顯示列表的生命週期。即使你想要的時候設置了標誌,你也不會得到你想要的行爲。

這裏有兩種解決方案:創建您自己的位圖或更好,只需啓用視圖上的圖形緩存,並且不要從onDraw()調用canvas.drawBitmap(getDrawingCache(), ...)。無論如何,家長會爲你做!

+0

我的視圖基本上是一個帶有自定義繪圖的大畫布。我正在繪製像這樣的_into_繪圖緩存: cache_canvas.setBitmap(getDrawingCache()); perform_drawing_into_cache_canvas。 我是否應該禁用緩存,如果我使用自己的位圖? – aragaer

+0

是的,這是正確的。 –