#1. 图片缓存策略
#2. Picaso 图片网络框架的实现
Picasso.with(mContext).load(url)
.into(holder.ivIcon);
强大功能? 时间\资源消耗 处理优化的好?
#3. Davinci
Davinci.with(mContext).load(url)
.placeHolder(R.drawable.acq)
.error(R.drawable.a4h)
.into(holder.ivIcon);
### 1. Davinci.with(mContext)
/*** 获取该类的实例
* @param context
* @return
*/
public static Davinci with(Context context) {
mContext = context;
mCacheMap = new LruCache<>(10*1024*1024);
//构建一个线程池,里面含有5个线程
mExecutorService = Executors.newFixedThreadPool(5);
return singleton;
}
### 2. load(url)
/**
* 也是返回一个实例 RequestCreator
* @param path
* @return
*/
public RequestCreator load(String path) {
return new RequestCreator(path);
}
public RequestCreator(String path) {
this.path = path;
}
### 3. placeHolder(R.drawable.acq)
public RequestCreator placeHolder(int resId) {
this.placeHolderResId = resId;
return this;
}
### 4. error(R.drawable.a4h)
public RequestCreator error(int resId) {
this.errorResId = resId;
return this;
}
### 5. into(holder.ivIcon);
public void into(ImageView imageView) {
this.imageView = imageView;
//还没有得到图片前先显示默认图片
imageView.setImageResource(placeHolderResId);
Bitmap bitmap = getBitmapFromCache();
Log.d(TAG, "into: 将要请求图片");
//1.内存中有图片
if (bitmap != null) {
Log.d(TAG, "into: 内存中有图片,直接显示");
imageView.setImageBitmap(bitmap);
return;
}
Log.d(TAG, "into: 内存没有,去磁盘中查找");
//2.内存中没有,磁盘中有图片
bitmap = getBitmapFromFile();
if (bitmap != null) {
//把图片存在内存
Log.d(TAG, "into: 磁盘中有图片,直接显示,并且存储到内存");
mCacheMap.put(path, bitmap);
imageView.setImageBitmap(bitmap);
return;
}
Log.d(TAG, "into: 磁盘没有图片,去网络获取");
//3.内存\磁盘都没有图片 ,则从网络下载
getBitmapFromNet();
}
*1. 去内存中查找
所谓的内存其实就是一些容器集合 (map , List , set , 数组... )
/**
* 去内存中获取图片
* @return bitmap
*/
private Bitmap getBitmapFromCache() {
// http://localhost:8080/aaa/bb/cc.jpg
//这个key其实可以使用url,
return mCacheMap.get(path);
}
*2. 去磁盘中查找
private Bitmap getBitmapFromFile() {
//有可能得到的这个缓存路径是null , 因为也许没有这张图片
String filePath = getCacheFilePath();
Bitmap bitmap = null;
if (!TextUtils.isEmpty(filePath)) {
bitmap = BitmapFactory.decodeFile(filePath);
}
return bitmap;
}
*3. 去网络获取
private void getBitmapFromNet() {
mExecutorService.submit(new LoadImageTask());
}
class LoadImageTask implements Runnable{
@Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(1200);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
//转化输入流成bitmap
InputStream is = conn.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(is);
//1.存到磁盘 把位图存成一张图片
FileOutputStream fos = new FileOutputStream(getCacheFilePath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
Log.d(TAG, "into: 获取网络图片成功, 存到内存与磁盘,直接显示");
//2.存到内存
mCacheMap.put(path, bitmap);
//3.显示图片
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
}, 1200);
} else {
showErrorPic();
}
} catch (Exception e) {
//请求图片失败
e.printStackTrace();
showErrorPic();
}
}
}
##优化:
* 1. 线程池
* 2. 内存的缓存 2.3前 SoftReference<Bitmap>
4.0后 一视同仁了,都一样
存 :
new SoftReference<Bitmap>(bitmap)
取 :
SoftReference<Bitmap> reference = mCacheMap.get(path);
Bitmap bitmap = null;
if (reference != null){
bitmap = reference.get();
}
* 3. 不用bitmap, 用LruCache<K,V>
packageManager.freeStoreAndNotify(Integer.Max_VALUE)
* 4. diskLruChe, 限定磁盘图片存储空间的大小
(网上有, 官方没给出来)
#4. JAVA的引用类型 Reference
* 强引用
> 一般我们直接new出来的对象都属于强引用. 即使内存不足,宁愿抛出内存溢出异常,也不回收这个对象的内存
* 软引用
> SoftReference 内存不足,就回收该对象
* 弱引用
> WeakReference GC 出来,就回收对象
* 虚引用
> PhantomReference 用过该对象,就没了。 释放内存。
#5. 问题: 处理listView的时候,出现图片错乱
解决方案
Map<imageView, url>
map.put(iv1, 01的路径)
iv1, 01.jpg
iv2, 02.jpg
...
iv5, 05.jpg
得到图片的时候
run(){
String oldUrl = map.get(iv);
if(oldUrl.equal(url)){
赋值
}
}
##在子线程加载图片 AsyncDrawable处理并发问题
官方文档:Develop-
->Training
-->Building Apps with Graphics&Animation
-->Processing Bitmaps Off the UI Thread
-->Handle ConCurrent
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}