【android相册】加载相册中的图片,实现图片缓存

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

读取本地图库中的文件,加载到内存中,使用recyclerView显示


一、读取相册文件

使用ContenResolver查询相册文件,MediaStore.Images.Media.EXTERNAL_CONTENT_URI系统相册的文件目录。

 ContentResolver resolver = context.getContentResolver();
            Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID));
                        Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
                        arrayList.add(uri);
                    }
                }

二、图片缓存原理

先从内存中寻找图片,未找到再从文件中寻找图片。找到之后加入缓存中。
在这里插入图片描述

public void displayImage(Uri uri, ImageView view, Handler handler) {
        //异步加载
        Runnable displayTask = new Runnable() {
            @Override
            public void run() {
            //从内存中加载
                Bitmap bitmapFromCache = baseMemoryCache.get(String.valueOf(uri));
                if (bitmapFromCache != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            view.setImageBitmap(bitmapFromCache);
                        }
                    });
                    return;
                }
                //从文件中加载
                InputStream inputStream = null;
                try {
                    inputStream = resolver.openInputStream(uri);
                    InputStream stream = resolver.openInputStream(uri);
					//压缩图片
                    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeStream(inputStream, null, options);
                    options.inSampleSize = 4;
                    options.inJustDecodeBounds = false;

                    Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
                    baseMemoryCache.put(String.valueOf(uri), bitmap);
                    Log.e("BItmap: ", bitmap + "");
                    hashMap.put(uri, bitmap);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            view.setImageBitmap(bitmap);
                        }
                    });

                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        //开始加载
        threadPoolExecutor.execute(displayTask);
    }

三、类图

在这里插入图片描述

四、Imageloader源码解析

1.从内存加载图片

Imageloader获取实例,单例实现。

在这里插入图片描述

再看imageloader的displayImage方法,传入参数
uri 图片地址
ImageAware 传入view,图片显示的View
DisplayOptions 显示的一些参数
ImageSize 图片大小
还有两个加载监听
在这里插入图片描述
前面是一些ImageWare、listener的一些检查操作,下面是从内存中获取缓存。
在这里插入图片描述

然后跟进ProcessAndDisplayTask,ProcessAndDisplayTask实现了Runable接口。使用BitmapProcessor处理bitmap,然后调用LoadandDisplayImageTask.runTask
在这里插入图片描述
进入LoadAndDisplayImageTask.runTask

在这里插入图片描述
执行loadAndDisplayImageloader的run方法,进入displayer
在这里插入图片描述
displayer很简单,就是setImageBitmap显示图片。至此,图片已经显示到了IamgeView中
在这里插入图片描述
再来看看Imageloader如何保存在内存中保存图片的。
先看BaseMemoryCache
在这里插入图片描述
除了BaseMemory,Imageloader还不同的方式缓存图片,例如LRU、FIFO
等。
在这里插入图片描述

2.从文件中加载图片

如果内存中没找到,就从文件中找。
在这里插入图片描述
进入ImageEngine看看
在这里插入图片描述
打开文件,得到输入流
在这里插入图片描述

Imageloader支持Http、fill、以及资源文件读取图片。
在这里插入图片描述
然后再看看打开文件的方法
在这里插入图片描述

总结

Imageloader支持从文件、内存、网络中读取图片。支持同步加载和异步加载,内部实现了默认线程池加载,并同时支持对显示图片的裁剪和压缩。提高加载速度。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值