android大图加载问题解决的心路历程

  最近有一个小的需求,是替换项目中预览大图的实现。作为互联网医疗类公司,大图预览对我们公司来说是刚需,因为患者经常会把在医院拍的片通过客户端上传之后发给医生看,要知道有的患者上传的图片可以达到20m。受限于android应用的内存限制,加载大图常会出现OOM。最终我决定采用的方案是:将整个Bitmap分割成很多方块,使用BitmapRegionDecoder来区间加载这些小的Bitmap,铺满整个屏幕。由于开发时间比较紧张,我们倾向于选择成熟的第三方,在查找了一些资料后,我选择subsampling-scale-image-view来支持大图加载。

  根据github上subsampling-scale-image-view的主页的描述,我下载了相关源码,运行了一下,并且在viewpager的情况下加载多张33M的大图,未出现OOM,证明这个控件是满足我的需求的。

  事先,我根据subsampling-scale-image-view的主页信息,我认为subsampling-scale-image-view只支持本地图片文件,不支持url,不支持bitmap,在这种局限下,我的想法是建立一个可动态管理的缓存来配合subsampling-scale-image-view使用,最终我在选择自己实现动态缓存管理和使用第三方之中,选择使用第三方,我选择的是disklrucache,结合universal imageloader的源码以及洪洋的封装,我尝试对它做了一层封装,提供了一些更易用的方法供外界调用。事实上它也工作良好。

  当晚,我对subsampling-scale-image-view github上的issue都阅读了一遍,基本上知道了这个控件可能存在的问题和解决方案,同时我还获得了一个非常重要的信息——subsampling-scale-image-view是支持bitmap直接加载的。最终我认为既然如此,在缩略图加载的时候,我可以尝试使用直接加载bitmap的方案,只有在下载原图后加载的时候我再选择加载本地原图的方案。

鉴于我们公司项目图片加载采用的是picasso,我尝试使用

        Picasso.with(getActivity()).load(mUrl).resize(720, 1080).into(new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
            ImageSource imageSource = ImageSource.bitmap(bitmap);
            mImageView.setImage(imageSource);
        }

        @Override
        public void onBitmapFailed(Drawable drawable) {

        }

        @Override
        public void onPrepareLoad(Drawable drawable) {

        }
    });

  不过这方案貌似并不好用,在我第一次进入预览页面的时候,图片总是加载不出来,第二进去就好了,我认为是subsampling-scale-image-view的问题,在结合debug阅读了subsampling-scale-image-view源码后,我认为subsampling-scale-image-view并无此问题,之后,我才把怀疑转到了picasso身上,我认为极有可能是Target没有被回调,在打印日志后,我验证了这种想法,确实是picasso的问题。在简单的google后,我尝试修改picasso加载图片的代码如下:

private Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
            ImageSource imageSource = ImageSource.bitmap(bitmap);
            mImageView.setImage(imageSource);
        }

        @Override
        public void onBitmapFailed(Drawable drawable) {

        }

        @Override
        public void onPrepareLoad(Drawable drawable) {

        }
    };


        Picasso.with(getActivity()).load(mUrl).resize(720, 1080).into(target);

这个时候终于好了。

我的一些思考:
1.遇到问题,列出各种可能的原因,一一去验证,不要避开问题。
2.选择一个第三方的时候,一定要把它相关的issue都阅读一遍,保证自己对这个第三方足够熟悉。

你可能感兴趣的:(android提高)