Android图片下载缓存库picasso解析
- - 移动开发 - ITeye博客picasso是Square公司开源的一个Android图形缓存库,地址 http://square.github.io/picasso/,可以实现图片下载和缓存功能. picasso使用简单,如下. 在adapter中回收和取消当前的下载;. 使用最少的内存完成复杂的图形转换操作;. 图形转换操作,如变换大小,旋转等,提供了接口来让用户可以自定义转换操作;.
picasso是Square公司开源的一个Android图形缓存库,地址 http://square.github.io/picasso/,可以实现图片下载和缓存功能。
picasso使用简单,如下
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
主要有以下一些特性:
this.map = new LinkedHashMap<String, Bitmap>(0, 0.75f, true);
private void trimToSize(int maxSize) {
while (true) {
String key;
Bitmap value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}
if (size <= maxSize || map.isEmpty()) {
break;
}
Map.Entry<String, Bitmap> toEvict = map.entrySet().iterator()
.next();
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= Utils.getBitmapBytes(value);
evictionCount++;
}
}
}
public interface Transformation {
/**
* Transform the source bitmap into a new bitmap. If you create a new bitmap instance, you must
* call {@link android.graphics.Bitmap#recycle()} on {@code source}. You may return the original
* if no transformation is required.
*/
Bitmap transform(Bitmap source);
/**
* Returns a unique key for the transformation, used for caching purposes. If the transformation
* has parameters (e.g. size, scale factor, etc) then these should be part of the key.
*/
String key();
}
@Override
public void complete(Bitmap result, Picasso.LoadedFrom from) {
if (result == null) {
throw new AssertionError(String.format(
"Attempted to complete action with no result!\n%s", this));
}
ImageView target = this.target.get();
if (target == null) {
return;
}
Context context = picasso.context;
boolean debugging = picasso.debugging;
PicassoDrawable.setBitmap(target, context, result, from, noFade,
debugging);
if (callback != null) {
callback.onSuccess();
}
}
public void run() {
try {
Thread.currentThread()
.setName(Utils.THREAD_PREFIX + data.getName());
result = hunt();
if (result == null) {
dispatcher.dispatchFailed(this);
} else {
dispatcher.dispatchComplete(this);
}
} catch (IOException e) {
exception = e;
dispatcher.dispatchRetry(this);
} catch (Exception e) {
exception = e;
dispatcher.dispatchFailed(this);
} finally {
Thread.currentThread().setName(Utils.THREAD_IDLE_NAME);
}
}
abstract Bitmap decode(Request data) throws IOException;
Bitmap hunt() throws IOException {
Bitmap bitmap;
if (!skipMemoryCache) {
bitmap = cache.get(key);
if (bitmap != null) {
stats.dispatchCacheHit();
loadedFrom = MEMORY;
return bitmap;
}
}
bitmap = decode(data);
if (bitmap != null) {
stats.dispatchBitmapDecoded(bitmap);
if (data.needsTransformation() || exifRotation != 0) {
synchronized (DECODE_LOCK) {
if (data.needsMatrixTransform() || exifRotation != 0) {
bitmap = transformResult(data, bitmap, exifRotation);
}
if (data.hasCustomTransformations()) {
bitmap = applyCustomTransformations(
data.transformations, bitmap);
}
}
stats.dispatchBitmapTransformed(bitmap);
}
}
return bitmap;
}
void dispatchSubmit(Action action) {
handler.sendMessage(handler.obtainMessage(REQUEST_SUBMIT, action));
}
handler接到消息后转换到performSubmit方法
void performSubmit(Action action) {
BitmapHunter hunter = hunterMap.get(action.getKey());
if (hunter != null) {
hunter.attach(action);
return;
}
if (service.isShutdown()) {
return;
}
hunter = forRequest(context, action.getPicasso(), this, cache, stats,
action, downloader);
hunter.future = service.submit(hunter);
hunterMap.put(action.getKey(), hunter);
}
public static Picasso with(Context context) {
if (singleton == null) {
singleton = new Builder(context).build();
}
return singleton;
}
public Picasso build() {
Context context = this.context;
if (downloader == null) {
downloader = Utils.createDefaultDownloader(context);
}
if (cache == null) {
cache = new LruCache(context);
}
if (service == null) {
service = new PicassoExecutorService();
}
if (transformer == null) {
transformer = RequestTransformer.IDENTITY;
}
Stats stats = new Stats(cache);
Dispatcher dispatcher = new Dispatcher(context, service, HANDLER,
downloader, cache, stats);
return new Picasso(context, dispatcher, cache, listener,
transformer, stats, debugging);
}
在Picasso.with()的时候会将执行所需的所有必备元素创建出来,如缓存cache、执行executorService、