Domanda

I have a custom view that is manually drawn. I am drawing stuff into bitmap, then use that bitmap in onDraw(). I realized that if I enable drawing cache I can use that cache instead of creating my own bitmap. This mostly works.

Currently my onDraw method looks like this:

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

This properly works on emulators I've tried. However I'm getting crash reports on StackOverflowError. The report looks like this:

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...

I've looked at android source and in fact buildDrawingCache calls draw(). This would explain the loop. But buildDrawingCache() should have returned immediately on second call.

This does not happen though unless PFLAG_DRAWING_CACHE_VALID is set (source). And that flag is not set only if view is attached to a parent, IS hardware accelerated AND layer type is LAYER_TYPE_NONE (source again).

The question is - is it OK to explicitly set layer type to something not-none or I should use some other approach? If yes, which type I should choose?

È stato utile?

Soluzione

getDrawingCache() was never meant to be used by a View itself. It is managed by the parent. The reason why the flag is not set when the View is hardware accelerated is because the "drawing cache" takes on a different meaning with hardware acceleration. It is used to control the lifecycle of display lists. Even if the flag was set when you'd want it, you wouldn't get the behavior you want.

There are two solutions here: create your own bitmap or better yet, just enable the drawing cache on your View and don't call canvas.drawBitmap(getDrawingCache(), ...) from onDraw(). The parent will do it for you anyway!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top