Android Frame based animation memory problem

Posted by madsleejensen on Stack Overflow See other posts from Stack Overflow or by madsleejensen
Published on 2011-01-13T14:50:59Z Indexed on 2011/01/13 14:53 UTC
Read the original article Hit count: 216

Filed under:

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;
        }
    }
}

© Stack Overflow or respective owner

Related posts about android