title: Is this a good solution to cycling through images?
body: <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>