使用Glide将位图加载到ImageView中

时间:2016-10-04 12:45:45

标签: android bitmap android-asynctask android-recyclerview android-glide

背景

我的应用中有RecyclerView(使用GridLayoutManager),需要显示本地存储的一些敏感加密图像。

我不能使用这样的东西,

  Glide.with(this).load(encryptedImageFile).into(imageView);

因为我首先需要解密它们然后设置图像。

我做了什么

我有一个AsyncTask解密这些小缩略图,并在ImageView中设置了一个结果Bitmap。

以下是Adapter和AsyncTask的一些小代码片段。

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

AsyncTask解密并将Bitmaps设置为ImageViews,

static class BindEncryptedThumbnail extends AsyncTask<Object, Void, Bitmap> {
    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 && StringUtils.equals(name, encryptedFileDBModel.getOriginalFileName())
                && (thumbnail != null) && (mHolder.mImage != null)) {
            mHolder.mImage.setImageBitmap(thumbnail);
        } else {
            mHolder.mImage.setImageDrawable(ResourceUtils.getDrawable(R.drawable.img_placeholder));
        }
    }
}

问题

一切正常,图像正确解密并正确设置在RecyclerView项目中。但当有很多图像时,应用程序的内存占用量很高,并且有几个GC ,因为没有BitmapPool可以有效地加载图像。

我不想自己实现磁盘缓存和BitmapPool,因为这些已在Glide中有效完成( FYI,我在我的应用程序的其他部分使用Glide )。

我想使用Glide加载一个Bitmap(由我的AsyncTask返回)并将其设置为ImageView ,以便我可以解密我的图像并利用Glide提供的所有优点。

修改

添加有关我如何生成缩略图的更多信息。

public Bitmap getThumb(int thumbnailSize) {
        if ((!mThumbnailCreated) && (mThumbnailBitmap == null)) {
            CipherInputStream streamThumb = readStream();
            this.mThumbnailBitmap = ThumbnailEncryptionFactory
                    .getThumbnailfromStream(streamThumb, thumbnailSize);
        }
        return mThumbnailBitmap;
    }

这个,

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

0 个答案:

没有答案