I am working on a 2d tutorial and was able to test my current tutorial part on a Samsung Galaxy Tab.
The tutorial simply moves the default icon randomly over the screen.
Well, I've been looking on your project and everything seems to be fine, but I have one idea about what's causing you the frame rate drop.
You're allocating objects during runtime. If you don't do that, it will make you create all objects at start, and therefore you should notice a significant drop directly (if my solution doesn't solve your problem).
That said; I'm not sure whether an object pool will solve your problem, but you can try. Initialize your objects in a constructor and instead of making this call in onTouchEvent():
new Element(getResources(), (int) event.getX(), (int) event.getY())
You should have something like mElement.add(objectPool.allocate())
, where the object pool finds an unused object in the pool. Also, we should have a specified amount of objects in that object pool and from there you can check if it is the allocating that is causing this error or if it is something else.
With the 26th element the frame rate drops to 25fps.
When (or if) you implements this, you should see the frame rate drop directly (if this doesn't solve your problem though), since the object pool will make you allocating a fixed amount (e.g. maybe 100 elements?) at start (but you're not using them visually).
Also, I have used the memory pool pattern (object pool) in one of my sample applications for Android. In that sample; I add a line to the Canvas
on an onTouchEvent()
using an object pool (without allocating during runtime). In that source code you can easily change the total amounts of objects and check it out and try it yourself. Write a comment if you want to look at my sample application (and source code) and I will gladly share it since it's not public yet. My comments are in Swedish, but I think you should be able to understand, since the variables and methods are in English. :)
Side note: You wrote that you've tried (and even success) with removing the behaviour by making your Bitmap
static
. As it is right now, your elements have different instances of a Bitmap
, which will make you allocate a new Bitmap
everytime you're constructing a new object. That means that every object is pointing to a different Bitmap
when they are using the same resource. static
is a fully valid solution (although a magic number of 25 seems wierd).
This Bitmap
case can be compared to the OpenGL
system. If you have 20 objects which all should use the same resource, there are two possible solutions: They can point to the same VRAM texture or either they can point to a different VRAM texture (like your case when you're not using static
), but still same resource.
EDIT:
Here is my sample application for Android that demonstrates the Memory Pool.
Regarding your solution with BitmapFactory
, that probably depends on how that class works. I'm not sure, but I think that one of the decode...()
methods generates a new Bitmap
even if it is the same resource. It can be the case that new BufferedInputStream(res.openRawResource(R.drawable.icon))
is reusing the BufferedInputStream
from memory, although, that is a big guess.
What you should do (in that case) is to decode a resource and store a reference from it in the Panel class and pass that reference into the new Element(bitmapReference, ...)
instead. In that way, you're only allocating it once and every element is pointing to the same Bitmap
in memory.
I believe i can shed some light on this problem.
At least on my Galaxy S, Gingerbread 2.3.5 the first code loads my test.png into Bitmap with Bitmap.Config = ARGB_8888, while the second code loads with Bitmap.Config = RGB565. The strange thing is, while Gingerbread by default supposed to create 32bit surface, the RGB565 'renders' (I profiled and compared native call to drawBitmap) much faster.
Hence, The second idea, more appropriate for the your example as a whole, is that ARGB888 Bitmap does have alpha, so in that case rendering overlapping images of 25+ sprites could create some bottleneck in alpha calculation algorithm, while RGB565 image would be fine and fast.
I have tried your code on HTC Desire HD and the frame rate drops down to unusable after added 20th image using Android 2.2 target. When I exported the same code as android version 2.1 then it worked fine and could handle over 200 instances! I suspect that it is to do with creating instances of your GraphicObject class on 2.2, but not quite sure...