title: Load Bitmap Into ImageView using Glide
body: <p><strong>Background</strong></p>
  
  <p>I have a <code>RecyclerView</code> (with GridLayoutManager) in my app which needs to show some sensitive encrypted images stored locally.</p>
  
  <p>I cannot use something like this,</p>
  
  <pre><code>  Glide.with(this).load(encryptedImageFile).into(imageView);
  </code></pre>
  
  <p>as I first need to decrypt them and then set the image.</p>
  
  <p><strong>What I Have Done</strong></p>
  
  <p>I have an AsyncTask which decrypts those small thumbnail images and gives me a resulting Bitmap to set in the ImageView.</p>
  
  <p>Here are some small code snippets of the Adapter and the AsyncTask.</p>
  
  <pre><code>@Override
      public void onBindViewHolder(MediaViewHolder holder, int position) {
          super.onBindViewHolder(holder, position);
  
          EncryptedFileContainer encryptedFileContainer = getItem(position);
  
          if (encryptedFileContainer != null) {
              EncryptedFileDBModel encryptedFileDBModel = encryptedFileContainer.getEncryptedFileDBModel();
              holder.mImage.setTag(encryptedFileDBModel.getOriginalFileName());
  
              new BindEncryptedThumbnail(holder, encryptedFileContainer).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
          }
      }
  </code></pre>
  
  <p>The AsyncTask to decrypt and set Bitmaps to the ImageViews,</p>
  
  <pre><code>static class BindEncryptedThumbnail extends AsyncTask&lt;Object, Void, Bitmap&gt; {
      private EncryptedFileContainer mEncryptedFileContainer;
      private MediaViewHolder mHolder;
  
      public BindEncryptedThumbnail(MediaViewHolder viewHolder, EncryptedFileContainer encryptedFileContainer) {
          this.mHolder = viewHolder;
          this.mEncryptedFileContainer = encryptedFileContainer;
      }
  
      protected Bitmap doInBackground(Object... objects) {
          if (mEncryptedFileContainer.getEncryptedFile() != null) {
              return mEncryptedFileContainer.getDecryptedThumb().getThumb(100);
          } else {
              return null;
          }
      }
  
      protected void onPostExecute(Bitmap thumbnail) {
          String name = (String) mHolder.mImage.getTag();
          EncryptedFile encryptedFile = mEncryptedFileContainer.getEncryptedFile();
          EncryptedFileDBModel encryptedFileDBModel = mEncryptedFileContainer.getEncryptedFileDBModel();
          if (encryptedFile != null &amp;&amp; StringUtils.equals(name, encryptedFileDBModel.getOriginalFileName())
                  &amp;&amp; (thumbnail != null) &amp;&amp; (mHolder.mImage != null)) {
              mHolder.mImage.setImageBitmap(thumbnail);
          } else {
              mHolder.mImage.setImageDrawable(ResourceUtils.getDrawable(R.drawable.img_placeholder));
          }
      }
  }
  </code></pre>
  
  <p><strong>The Problem</strong></p>
  
  <p>Everything works fine and images are decrypted properly and being set in the RecyclerView items correctly. But <strong>when there are lots of images the memory footprint of the app shoots high up and there are several GCs</strong> as there is no BitmapPool to efficiently load images.</p>
  
  <p>I would not like to implement disk caching and BitmapPool by myself as these have been effectively done in Glide (<em>FYI, I am using Glide in other parts of my app</em>). </p>
  
  <p><strong>I would like to use Glide to load a Bitmap (returned by my AsyncTask) and set it into the ImageView</strong> so that I can decrypt my images and also make use of all the goodness Glide offers.</p>
  
  <p><strong>EDIT</strong>:</p>
  
  <p>Adding more information on how I am generating the thumbnail.</p>
  
  <pre><code>public Bitmap getThumb(int thumbnailSize) {
          if ((!mThumbnailCreated) &amp;&amp; (mThumbnailBitmap == null)) {
              CipherInputStream streamThumb = readStream();
              this.mThumbnailBitmap = ThumbnailEncryptionFactory
                      .getThumbnailfromStream(streamThumb, thumbnailSize);
          }
          return mThumbnailBitmap;
      }
  </code></pre>
  
  <p>and this, </p>
  
  <pre><code>public static Bitmap getThumbnailfromStream(CipherInputStream streamThumb, int size) {
          if (streamThumb != null) {
              try {
                  byte[] bytes = IOUtils.toByteArray(streamThumb);
                  return decodeSampledBitmapFromByte(bytes, size, size);
              } catch (IOException e) {
                  Timber.d("Error decoding thumbnail.");
              }
          }
          return null;
      }
  
  public static Bitmap decodeSampledBitmapFromByte(byte[] stream, int reqWidth, int reqHeight) {
          BitmapFactory.Options options = new BitmapFactory.Options();
          options.inJustDecodeBounds = true;
          BitmapFactory.decodeByteArray(stream, 0, stream.length, options);
  
          options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  
          // Decode bitmap with inSampleSize set
          options.inJustDecodeBounds = false;
          return BitmapFactory.decodeByteArray(stream, 0, stream.length, options);
      }
  </code></pre>