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


前言

读取本地图库中的文件,加载到内存中,使用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支持从文件、内存、网络中读取图片。支持同步加载和异步加载,内部实现了默认线程池加载,并同时支持对显示图片的裁剪和压缩。提高加载速度。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐