Android Frame based animation memory problem
- by madsleejensen
Hi all
Im trying to create a animation on top of a Camera Surface view. The animation if a box rotating, and to enable transparency i made a bunch of *.png files that i want to just switch out on top of the Camera view.
The problem is Android wont allow me to allocate so many images (too much memory required) so the AnimationDrawable is not an option.
Will i be able to allocate all the *.png bitmaps if i use OpenGL instead? then i would store all the *.png's as Textures and just make my own animation logic? is am i under the same restrictions there?
Any ideas on how to solve this problem ?
Ive made a Custom view that loads the image resource on every frame and discards it when next frame is to be displayed. But the performance is terrible.
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.util.Log;
import android.widget.ImageView;
public class FrameAnimationView extends ImageView
{
private int mFramesPerSecond = 10;
private int mTimeBetweenFrames = (1000 / mFramesPerSecond);
private int mCurrentFrame = 1;
private String[] mFrames;
private Thread mAnimationThread;
private Resources mResources;
private String mIdentifierPrefix;
private Activity mContext;
private boolean mIsAnimating = false;
private Integer[] mDrawableIndentifiers;
public FrameAnimationView(Activity context, String[] frames)
{
super(context);
mContext = context;
mResources = context.getResources();
mFrames = frames;
mIdentifierPrefix = context.getPackageName() + ":drawable/";
mDrawableIndentifiers = new Integer[frames.length];
}
private void initAnimationThread()
{
mAnimationThread = new Thread(new Runnable()
{
@Override
public void run()
{
while (mIsAnimating)
{
final int frameToShow = (mCurrentFrame - 1);
//Log.e("frame", Integer.toString(frameToShow));
mContext.runOnUiThread(new Runnable()
{
@Override
public void run()
{
if (mDrawableIndentifiers[frameToShow] == null)
{
String frameId = mFrames[frameToShow];
int drawableResourceId = mResources.getIdentifier(mIdentifierPrefix + frameId, null, null);
mDrawableIndentifiers[frameToShow] = drawableResourceId;
}
Drawable frame = getResources().getDrawable(mDrawableIndentifiers[frameToShow]);
setBackgroundDrawable(frame);
if (mCurrentFrame < mFrames.length)
{
mCurrentFrame++;
}
else
{
mCurrentFrame = 1;
}
}
});
try
{
Thread.sleep(mTimeBetweenFrames);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
});
}
public void setFramesPerSecond(int fps)
{
mFramesPerSecond = fps;
mTimeBetweenFrames = (1000 / mFramesPerSecond);
}
public void startAnimation()
{
if (mIsAnimating) return;
mIsAnimating = true;
initAnimationThread();
mAnimationThread.start();
}
public void stopAnimation()
{
if (mIsAnimating)
{
Thread oldThread = mAnimationThread;
mAnimationThread = null;
oldThread.interrupt();
mIsAnimating = false;
}
}
}