提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
读取本地图库中的文件,加载到内存中,使用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支持从文件、内存、网络中读取图片。支持同步加载和异步加载,内部实现了默认线程池加载,并同时支持对显示图片的裁剪和压缩。提高加载速度。