Android中大量图片加载所造成的OOM解决办法

背景

由于是初次接触Android开发,老师分配给我的是项目中相册开发部分。

思路

项目要求是需要从大疆无人机上获取到图片视频,因为调试麻烦,所以先获取Pad上的媒体文件进行模拟。
当时的想法是获取到文件后,在PhotoPreActivity中直接把全部文件加载到ImagePagerAdapter中。

List<ImageView> mViews = new ArrayList<>();
int size = mDatas.size();
for (int i = 0; i < size; i++) {
	ImageView view = new ImageView(this);
    mViews.add(view);
}
mImagePagerAdapter = new ImagePagerAdapter(this, mViews);
bigImgVp.setAdapter(mImagePagerAdapter);

测试时,在进行大图浏览的过程中,程序开始卡顿然后突然崩溃,使用ASProfile发现在进行浏览时,内存一直在不停地增加。

解决方案

一、使用Glide与PhotoView

导入Glide与PhotoView的依赖

    implementation 'com.github.chrisbanes.photoview:library:+'
    implementation 'com.github.bumptech.glide:glide:4.5.0'

使用缩略图来提高加载速度和降低内存占用。根据控件大小对图片进行裁剪,减少不必要内存浪费。

RequestOptions myOptions = new RequestOptions()
                    .fitCenter()
                    .placeholder(R.mipmap.ic_launcher)
                    .error(R.mipmap.ic_launcher)
                    .skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.ALL);

Glide.with(context)
         .load(new File(path[section][position]))
         .transition(withCrossFade())            // .crossFade()()
         .apply(centerCropTransform())           // .centerCrop()
         .apply(myOptions)
         .thumbnail(0.5f)
         .into(viewHolder.thumb);
Glide.with(mContext)
         .load(photo.getPath())            
         .into(new SimpleTarget<Drawable>() {
         @Override
         public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                  photoView.setImageDrawable(resource);
             }
         });

虽然相比之前效果好点了,然而在浏览四十张图片后,内存开始暴涨,随后程序崩溃。

二、对ViewPager进行改进

Viewpager使用起来就是我们通过创建Adapter给它填充多个View,左右滑动时,切换不同的View。因为随着图片浏览的进行,ViewPager加载越来越多图片的时候就会OOM

  1. Viewpager里做资源回收;
  2. 保证Viewpager加载的mViews存储的图片为4个,分别是当前页,上一页,下一页以及下下一页。

ImagePagerAdapter

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (object instanceof PhotoView) {
            PhotoView view = (PhotoView) object;
            view.setImageDrawable(null);
            viewList.add(view);
            container.removeView((View) view);
        }
    }
   private void createImageViews() {
        for (int i = 0; i < 4; i++) {
            PhotoView imageView = new PhotoView(mContext);
            imageView.setAdjustViewBounds(true);
            viewList.add(imageView);
        }
    }

经过这两次改进后,到目前为止还未出现过OOM

附上GitHub GalleryDJI

猜你喜欢

转载自blog.csdn.net/sinat_27017647/article/details/87606471