Is this a good solution to cycling through images?
<p>I came up with a re-usable "BitmapHelper" class to help my app cycle through full-screen images.
I did this because the UI thread needs to update the ImageView and I don't want to use globals in my Activity to pass in the Bitmap and ImageView references.</p>

<p>The code below works but I observe <strong>Low Memory: No more background processes</strong> which has me worried about a memory leak</p>

<p><strong>The BitmapHelper class:</strong></p>

<pre><code>public class BitmapHelper
{
    //member variables
    private ImageView mImageView;
    private Bitmap mBitmap;
    private Activity mActivity;


    //constructor requires Activity and ImageView to work on
    // requiring the ImageView here implies that one BitmapHelper is used per ImageView
    public BitmapHelper(Activity activity, ImageView imageview)
    {
        mActivity = activity;
        mImageView = imageview;
    }


    //loadImageAsset(name of asset, i.e. "image.png")
    public void loadImageAsset(String assetfilename)
    {
        boolean bError = false;

        try
        {
            mBitmap = getBitmapFromAsset(assetfilename);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            bError = true;
        }

        //assign Bitmap to Imageview
        //NOTE!! this must be done in the UI thread or it's
        //       crash time when executed from another thread
        if (bError == false)
        {
            mActivity.runOnUiThread(new Runnable()
            {
                public void run()
                {
                    mImageView.setImageBitmap(mBitmap);
                }
            });
        }
    }


    //getBitmapFromAsset(name of asset, i.e. "image.png")
    public Bitmap getBitmapFromAsset(String assetfilename) throws IOException
    {
        AssetManager assetManager = mActivity.getAssets();

        InputStream istr = assetManager.open(assetfilename);
        Bitmap bitmap = BitmapFactory.decodeStream(istr);

        return bitmap;
    }

}
</code></pre>

<p><strong>The Activity:</strong></p>

<pre><code>public class myActivity extends Activity
{
    //member variables
    private String mFilenames[];
    private int mFilenameIndex;
    private ImageView mImageView;
    private Timer mTimerSeconds;
    private int mIntIdleSeconds;
    private BitmapHelper mBitmapHelper;

    //for logging
    private final String TAG = this.getClass().getSimpleName();


    @Override
    public void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.standby);

        //get references to UI components
        mImageView = (ImageView) findViewById(R.id.standby_imageview_adtop);

        //image slideshow
        mFilenames = new String[]{"pic1.png","pic2.png", "pic3.png"};
        mFilenameIndex = 0;
        mBitmapHelper = new BitmapHelper(this, mImageView);
        mBitmapHelper.loadImageAsset(mFilenames[mFilenameIndex]);

        //timer
        startSlideshowTimer();
    }


    @Override
    protected void onDestroy()
    {
        Log.d(TAG, "onDestroy()");
        if (mTimerSeconds != null)
        {
            mTimerSeconds.cancel();
        }
        super.onDestroy();
    }



    /**
     * timer functions
     */

    //start the slideshow timer
    public void startSlideshowTimer()
    {

        //initialize idle counter
        mIntIdleSeconds=0;

        //create timer to tick every second
        mTimerSeconds = new Timer();
        mTimerSeconds.schedule(new TimerTask()
        {
            @Override
            public void run()
            {
                timerSecondsCounter();
            }
        }, 0, 1000);
    }


    //called every second to count idle time and to update clock on Welcome screen
    private void timerSecondsCounter()
    {

        mIntIdleSeconds++;

        if (mIntIdleSeconds == Constants.MAX_AD_TIME_SECONDS)
        {
            //cycle to next image
            mFilenameIndex++;
            if (mFilenameIndex == mFilenames.length)
            {
                mFilenameIndex=0;
            }

            mBitmapHelper.loadImageAsset(mFilenames[mFilenameIndex]);

            //reset counter
            mIntIdleSeconds=0;
        }

    }//end of: timerSecondsCounter()

}
</code></pre>

<p>for testing, I set <strong>Constants.MAX_AD_TIME_SECONDS = 1</strong> and the app cycles through an image every second. It's cool to watch but the ActivityManager is shutting down other processes.</p>

<p>am I doing it wrong or right ?</p>

<p>note: the images are about 130KB to 280KB big</p>

<hr>

<p>EDIT: as suggested I have updated my BitmapHelper class to pre-load the images. See the following ...</p>

<pre><code>public class BitmapHelper
{
    //member variables
    private ImageView mImageView;
    private Bitmap mBitmap;
    private Activity mActivity;

    private Map&lt;String,Bitmap&gt; mBitHashmap;


    //constructor requires Activity and ImageView to work on
    // requiring the ImageView here implies that one BitmapHelper is used per ImageView
    public BitmapHelper(Activity activity, ImageView imageview)
    {
        mActivity = activity;
        mImageView = imageview;
        mBitHashmap = new HashMap&lt;String,Bitmap&gt;();
    }


    //loadAndShowImageAsset(name of asset, i.e. "image.png")
    //NOTE: avoid doing too many of these, otherwise the heap is used-up
    //      and the ActivityManager starts closing down background activities
    public void loadAndShowImageAsset(String assetfilename)
    {
        boolean bError = false;

        try
        {
            mBitmap = getBitmapFromAsset(assetfilename);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            bError = true;
        }

        //assign Bitmap to Imageview
        //NOTE!! this must be done in the UI thread or it's
        //       crash time when executed from another thread
        if (bError == false)
        {
            mActivity.runOnUiThread(new Runnable()
            {
                public void run()
                {
                    mImageView.setImageBitmap(mBitmap);
                }
            });
        }
    }


    //putImageInBuffer(name of asset, i.e. "image.png")
    public void putImageInBuffer(String assetfilename)
    {
        try
        {
            Bitmap bitmap = getBitmapFromAsset(assetfilename);
            if (bitmap != null)
            {
                mBitHashmap.put(assetfilename, bitmap);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }


    //showImageInBuffer(name of asset, i.e. "image.png")
    //NOTE: pre-load all the images to memory and then use this to set the
    //      image in the ImageView. This is the heap-friendly way to do it.
    public void showImageInBuffer(String assetfilename)
    {
        mBitmap = mBitHashmap.get(assetfilename);

        if (mBitmap != null)
        {
            //assign Bitmap to Imageview
            //NOTE!! this must be done in the UI thread or it's
            //       crash time when executed from another thread
            mActivity.runOnUiThread(new Runnable()
            {
                public void run()
                {
                    mImageView.setImageBitmap(mBitmap);
                }
            });
        }
    }


    //getBitmapFromAsset(name of asset, i.e. "image.png")
    public Bitmap getBitmapFromAsset(String assetfilename) throws IOException
    {
        AssetManager assetManager = mActivity.getAssets();

        InputStream istr = assetManager.open(assetfilename);
        Bitmap bitmap = BitmapFactory.decodeStream(istr);

        return bitmap;
    }

}
</code></pre>

<p>Instead of using "loadImageAsset(), I now use showImageInBuffer() to display the image on the UI.
I've been testing this implementation for 15mins (cycling through images every second) and no nasty "Low Memory" messages have been witnessed.</p>
