/* * Copyright (C) 2013 Peng fei Pan <sky@xiaopan.me> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package me.xiaopan.sketch.request; import android.graphics.drawable.Drawable; import java.util.HashSet; import java.util.Set; import me.xiaopan.sketch.SLogType; import me.xiaopan.sketch.Sketch; import me.xiaopan.sketch.cache.MemoryCache; import me.xiaopan.sketch.drawable.RefBitmap; import me.xiaopan.sketch.drawable.RefBitmapDrawable; import me.xiaopan.sketch.util.SketchUtils; /** * 支持显示顺风车的请求 */ public class FreeRideDisplayRequest extends DisplayRequest implements FreeRideManager.DisplayFreeRide { private Set<FreeRideManager.DisplayFreeRide> displayFreeRideSet; public FreeRideDisplayRequest(Sketch sketch, DisplayInfo requestInfo, DisplayOptions displayOptions, ViewInfo viewInfo, RequestAndViewBinder requestAndViewBinder, DisplayListener displayListener, DownloadProgressListener downloadProgressListener) { super(sketch, requestInfo, displayOptions, viewInfo, requestAndViewBinder, displayListener, downloadProgressListener); } @Override public String getDisplayFreeRideLog() { return String.format("%s@%s", SketchUtils.toHexString(this), getKey()); } @Override public String getDisplayFreeRideKey() { return getKey(); } /** * 可以坐顺风车?条件是内存缓存key一样并且内存缓存可以用,没有单独关闭内存缓存,不解码GIF图片的请求,没有开同步执行,请求执行器可以用 */ @Override public boolean canByDisplayFreeRide() { MemoryCache memoryCache = getConfiguration().getMemoryCache(); return !memoryCache.isClosed() && !memoryCache.isDisabled() && !getOptions().isCacheInMemoryDisabled() && !getOptions().isDecodeGifImage() && !isSync() && !getConfiguration().getRequestExecutor().isShutdown(); } @Override protected void submitRunLoad() { // 可以坐顺风车的话,就先尝试坐别人的,坐不上就自己成为顺风车主让别人坐 if (canByDisplayFreeRide()) { FreeRideManager freeRideManager = getConfiguration().getFreeRideManager(); if (freeRideManager.byDisplayFreeRide(this)) { return; } else { freeRideManager.registerDisplayFreeRideProvider(this); } } super.submitRunLoad(); } @Override protected void runLoad() { super.runLoad(); // 由于在submitRunLoad中会将自己注册成为顺风车主,因此一定要保证在这里取消注册 if (canByDisplayFreeRide()) { FreeRideManager freeRideManager = getConfiguration().getFreeRideManager(); freeRideManager.unregisterDisplayFreeRideProvider(this); } } @Override public synchronized void byDisplayFreeRide(FreeRideManager.DisplayFreeRide request) { if (displayFreeRideSet == null) { synchronized (this) { if (displayFreeRideSet == null) { displayFreeRideSet = new HashSet<>(); } } } displayFreeRideSet.add(request); } @Override public Set<FreeRideManager.DisplayFreeRide> getDisplayFreeRideSet() { return displayFreeRideSet; } @Override public synchronized boolean processDisplayFreeRide() { MemoryCache memoryCache = getConfiguration().getMemoryCache(); RefBitmap cachedRefBitmap = memoryCache.get(getMemoryCacheKey()); if (cachedRefBitmap != null && cachedRefBitmap.isRecycled()) { memoryCache.remove(getMemoryCacheKey()); if (SLogType.REQUEST.isEnabled()) { printLogE("memory cache drawable recycled", "processFreeRideRequests", "bitmap=" + cachedRefBitmap.getInfo()); } cachedRefBitmap = null; } if (cachedRefBitmap != null) { // 立马标记等待使用,防止被挤出去回收掉 cachedRefBitmap.setIsWaitingUse(getLogName() + ":waitingUse:fromMemory", true); Drawable drawable = new RefBitmapDrawable(cachedRefBitmap); displayResult = new DisplayResult(drawable, ImageFrom.MEMORY_CACHE, cachedRefBitmap.getAttrs()); displayCompleted(); return true; } else { submitRunLoad(); return false; } } }