/*
* 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.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView.ScaleType;
import me.xiaopan.sketch.Configuration;
import me.xiaopan.sketch.SLogType;
import me.xiaopan.sketch.Sketch;
import me.xiaopan.sketch.SLog;
import me.xiaopan.sketch.display.ImageDisplayer;
import me.xiaopan.sketch.display.TransitionImageDisplayer;
import me.xiaopan.sketch.drawable.LoadingDrawable;
import me.xiaopan.sketch.drawable.RefBitmap;
import me.xiaopan.sketch.drawable.RefBitmapDrawable;
import me.xiaopan.sketch.drawable.ShapeBitmapDrawable;
import me.xiaopan.sketch.feature.ImageSizeCalculator;
import me.xiaopan.sketch.process.ImageProcessor;
import me.xiaopan.sketch.shaper.ImageShaper;
import me.xiaopan.sketch.state.StateImage;
import me.xiaopan.sketch.util.SketchUtils;
import me.xiaopan.sketch.util.Stopwatch;
/**
* 显示Helper,负责组织、收集、初始化显示参数,最后执行commit()提交请求
*/
public class DisplayHelper {
protected String logName = "DisplayHelper";
protected Sketch sketch;
protected DisplayInfo displayInfo = new DisplayInfo();
protected DisplayOptions displayOptions = new DisplayOptions();
protected DisplayListener displayListener;
protected DownloadProgressListener downloadProgressListener;
protected ViewInfo viewInfo = new ViewInfo();
protected ImageViewInterface imageViewInterface;
public DisplayHelper(Sketch sketch, String uri, ImageViewInterface imageViewInterface) {
init(sketch, uri, imageViewInterface);
}
public DisplayHelper(Sketch sketch, DisplayParams displayParams, ImageViewInterface imageViewInterface) {
init(sketch, displayParams, imageViewInterface);
}
/**
* 初始化
*/
public DisplayHelper init(Sketch sketch, String uri, ImageViewInterface imageViewInterface) {
this.sketch = sketch;
this.imageViewInterface = imageViewInterface;
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().start(logName + ". display use time");
}
// onDisplay一定要在最前面执行,因为在onDisplay中会设置一些属性,这些属性会影响到后续一些get方法返回的结果
this.imageViewInterface.onReadyDisplay(displayInfo.getUriScheme());
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("onDisplay");
}
displayInfo.reset(uri);
viewInfo.reset(imageViewInterface, sketch);
displayOptions.copy(imageViewInterface.getOptions());
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("init");
}
displayListener = imageViewInterface.getDisplayListener();
downloadProgressListener = imageViewInterface.getDownloadProgressListener();
return this;
}
/**
* 初始化,此方法用来在RecyclerView中恢复使用
*/
public DisplayHelper init(Sketch sketch, DisplayParams params, ImageViewInterface imageViewInterface) {
this.sketch = sketch;
this.imageViewInterface = imageViewInterface;
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().start(logName + ". display use time");
}
// onDisplay一定要在最前面执行,因为在onDisplay中会设置一些属性,这些属性会影响到后续一些get方法返回的结果
this.imageViewInterface.onReadyDisplay(displayInfo.getUriScheme());
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("onDisplay");
}
displayInfo.copy(params.info);
viewInfo.reset(imageViewInterface, sketch);
displayOptions.copy(params.options);
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("init");
}
displayListener = imageViewInterface.getDisplayListener();
downloadProgressListener = imageViewInterface.getDownloadProgressListener();
return this;
}
/**
* 重置所有属性
*/
public void reset() {
sketch = null;
displayInfo.reset(null);
displayOptions.reset();
displayListener = null;
downloadProgressListener = null;
viewInfo.reset(null, null);
imageViewInterface = null;
}
/**
* 禁用磁盘缓存
*/
@SuppressWarnings("unused")
public DisplayHelper disableCacheInDisk() {
displayOptions.setCacheInDiskDisabled(true);
return this;
}
/**
* 禁用BitmapPool
*/
@SuppressWarnings("unused")
public DisplayHelper disableBitmapPool() {
displayOptions.setBitmapPoolDisabled(true);
return this;
}
/**
* 设置请求Level
*/
public DisplayHelper requestLevel(RequestLevel requestLevel) {
if (requestLevel != null) {
displayOptions.setRequestLevel(requestLevel);
displayOptions.setRequestLevelFrom(null);
}
return this;
}
/**
* 解码Gif图片
*/
@SuppressWarnings("unused")
public DisplayHelper decodeGifImage() {
displayOptions.setDecodeGifImage(true);
return this;
}
/**
* 设置最大尺寸,在解码时会使用此Size来计算inSimpleSize
*/
@SuppressWarnings("unused")
public DisplayHelper maxSize(int width, int height) {
displayOptions.setMaxSize(width, height);
return this;
}
/**
* 裁剪图片,将原始图片加载到内存中之后根据resize进行裁剪。裁剪的原则就是最终返回的图片的比例一定是跟resize一样的,
* 但尺寸不一定会等于resize,也有可能小于resize,如果需要必须同resize一致可以设置forceUseResize
*/
public DisplayHelper resize(int width, int height) {
displayOptions.setResize(width, height);
return this;
}
/**
* 裁剪图片,将原始图片加载到内存中之后根据resize进行裁剪。裁剪的原则就是最终返回的图片的比例一定是跟resize一样的,
* 但尺寸不一定会等于resize,也有可能小于resize,如果需要必须同resize一致可以设置forceUseResize
*/
public DisplayHelper resize(int width, int height, ScaleType scaleType) {
displayOptions.setResize(new Resize(width, height, scaleType));
return this;
}
/**
* 使用ImageView的layout_width和layout_height作为resize
*/
@SuppressWarnings("unused")
public DisplayHelper resizeByFixedSize() {
displayOptions.setResizeByFixedSize(true);
return this;
}
/**
* 强制使经过resize处理后的图片同resize的尺寸一致
*/
public DisplayHelper forceUseResize() {
displayOptions.setForceUseResize(true);
return this;
}
/**
* 返回低质量的图片
*/
public DisplayHelper lowQualityImage() {
displayOptions.setLowQualityImage(true);
return this;
}
/**
* 设置图片处理器,图片处理器会根据resize和ScaleType创建一张新的图片
*/
@SuppressWarnings("unused")
public DisplayHelper processor(ImageProcessor processor) {
displayOptions.setImageProcessor(processor);
return this;
}
/**
* 设置图片质量
*/
@SuppressWarnings("unused")
public DisplayHelper bitmapConfig(Bitmap.Config config) {
displayOptions.setBitmapConfig(config);
return this;
}
/**
* 设置优先考虑质量还是速度
*/
@SuppressWarnings("unused")
public DisplayHelper inPreferQualityOverSpeed(boolean inPreferQualityOverSpeed) {
displayOptions.setInPreferQualityOverSpeed(inPreferQualityOverSpeed);
return this;
}
/**
* 开启缩略图模式
*/
@SuppressWarnings("unused")
public DisplayHelper thumbnailMode() {
displayOptions.setThumbnailMode(true);
return this;
}
/**
* 为了加快速度,将经过ImageProcessor、resize或thumbnailMode处理过的图片保存到磁盘缓存中,下次就直接读取
*/
@SuppressWarnings("unused")
public DisplayHelper cacheProcessedImageInDisk() {
displayOptions.setCacheProcessedImageInDisk(true);
return this;
}
/**
* 纠正图片的方向,让被旋转了的图片以正常方向显示
*/
@SuppressWarnings("unused")
public DisplayHelper correctImageOrientation() {
displayOptions.setCorrectImageOrientation(true);
return this;
}
/**
* 禁用内存缓存
*/
@SuppressWarnings("unused")
public DisplayHelper disableCacheInMemory() {
displayOptions.setCacheInMemoryDisabled(true);
return this;
}
/**
* 设置图片显示器,在加载完成后会调用此显示器来显示图片
*/
@SuppressWarnings("unused")
public DisplayHelper displayer(ImageDisplayer displayer) {
displayOptions.setImageDisplayer(displayer);
return this;
}
/**
* 设置正在加载时显示的图片
*/
@SuppressWarnings("unused")
public DisplayHelper loadingImage(StateImage loadingImage) {
displayOptions.setLoadingImage(loadingImage);
return this;
}
/**
* 设置正在加载时显示的图片
*/
@SuppressWarnings("unused")
public DisplayHelper loadingImage(int drawableResId) {
displayOptions.setLoadingImage(drawableResId);
return this;
}
/**
* 设置错误时显示的图片
*/
@SuppressWarnings("unused")
public DisplayHelper errorImage(StateImage errorImage) {
displayOptions.setErrorImage(errorImage);
return this;
}
/**
* 设置错误时显示的图片
*/
@SuppressWarnings("unused")
public DisplayHelper errorImage(int drawableResId) {
displayOptions.setErrorImage(drawableResId);
return this;
}
/**
* 设置暂停下载时显示的图片
*/
@SuppressWarnings("unused")
public DisplayHelper pauseDownloadImage(StateImage pauseDownloadImage) {
displayOptions.setPauseDownloadImage(pauseDownloadImage);
return this;
}
/**
* 设置暂停下载时显示的图片
*/
@SuppressWarnings("unused")
public DisplayHelper pauseDownloadImage(int drawableResId) {
displayOptions.setPauseDownloadImage(drawableResId);
return this;
}
/**
* 设置图片整型器,用于绘制时修改图片的形状
*/
@SuppressWarnings("unused")
public DisplayHelper shaper(ImageShaper imageShaper) {
displayOptions.setImageShaper(imageShaper);
return this;
}
/**
* 设置图片尺寸,用于绘制时修改图片的尺寸
*/
@SuppressWarnings("unused")
public DisplayHelper shapeSize(ShapeSize shapeSize) {
displayOptions.setShapeSize(shapeSize);
return this;
}
/**
* 设置图片尺寸,用于绘制时修改图片的尺寸
*/
@SuppressWarnings("unused")
public DisplayHelper shapeSize(int width, int height) {
displayOptions.setShapeSize(width, height);
return this;
}
/**
* 设置根据ImageView的layout_width和layout_height作为shape size
*/
@SuppressWarnings("unused")
public DisplayHelper shapeSizeByFixedSize() {
displayOptions.setShapeSizeByFixedSize(true);
return this;
}
/**
* 批量设置显示参数,这会是一个合并的过程,并不会完全覆盖
*/
public DisplayHelper options(DisplayOptions newOptions) {
displayOptions.merge(newOptions);
return this;
}
/**
* 批量设置显示参数,你只需要提前将DisplayOptions通过Sketch.putDisplayOptions()方法存起来,
* 然后在这里指定其名称即可,另外这会是一个合并的过程,并不会完全覆盖
*/
@SuppressWarnings("unused")
public DisplayHelper optionsByName(Enum<?> optionsName) {
return options(Sketch.getDisplayOptions(optionsName));
}
/**
* 提交请求
*/
public DisplayRequest commit() {
if (!SketchUtils.isMainThread()) {
SLog.w(SLogType.REQUEST, logName, "Please perform a commit in the UI thread. viewHashCode=%s. %s",
Integer.toHexString(imageViewInterface.hashCode()), displayInfo.getUri());
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().print(displayInfo.getUri());
}
sketch.getConfiguration().getHelperFactory().recycleDisplayHelper(this);
return null;
}
CallbackHandler.postCallbackStarted(displayListener, false);
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("callbackStarted");
}
preProcess();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("preProcess");
}
saveParams();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("saveParams");
}
boolean checkResult = checkUri();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("checkUri");
}
if (!checkResult) {
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().print(displayInfo.getKey());
}
sketch.getConfiguration().getHelperFactory().recycleDisplayHelper(this);
return null;
}
checkResult = checkMemoryCache();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("checkMemoryCache");
}
if (!checkResult) {
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().print(displayInfo.getKey());
}
sketch.getConfiguration().getHelperFactory().recycleDisplayHelper(this);
return null;
}
checkResult = checkRequestLevel();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("checkRequestLevel");
}
if (!checkResult) {
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().print(displayInfo.getKey());
}
sketch.getConfiguration().getHelperFactory().recycleDisplayHelper(this);
return null;
}
DisplayRequest potentialRequest = checkRepeatRequest();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("checkRepeatRequest");
}
if (potentialRequest != null) {
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().print(displayInfo.getKey());
}
sketch.getConfiguration().getHelperFactory().recycleDisplayHelper(this);
return potentialRequest;
}
DisplayRequest request = submitRequest();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().print(displayInfo.getKey());
}
sketch.getConfiguration().getHelperFactory().recycleDisplayHelper(this);
return request;
}
/**
* 对相关参数进行预处理
*/
protected void preProcess() {
Configuration configuration = sketch.getConfiguration();
ImageSizeCalculator imageSizeCalculator = sketch.getConfiguration().getImageSizeCalculator();
FixedSize fixedSize = viewInfo.getFixedSize();
// 用ImageVie的固定宽高作为shape size
ShapeSize shapeSize = displayOptions.getShapeSize();
if (shapeSize == null && displayOptions.isShapeSizeByFixedSize()) {
if (fixedSize != null) {
shapeSize = new ShapeSize(fixedSize.getWidth(), fixedSize.getHeight(), viewInfo.getScaleType());
displayOptions.setShapeSize(shapeSize);
} else {
throw new IllegalStateException("ImageView's width and height are not fixed," +
" can not be applied with the shapeSizeByFixedSize function");
}
}
// 如果没有设置ScaleType的话就从ImageView身上取
if (shapeSize != null && shapeSize.getScaleType() == null && imageViewInterface != null) {
shapeSize.setScaleType(viewInfo.getScaleType());
}
// 检查Resize的宽高都必须大于0
if (shapeSize != null && (shapeSize.getWidth() == 0 || shapeSize.getHeight() == 0)) {
throw new IllegalArgumentException("ShapeSize width and height must be > 0");
}
// 用ImageVie的固定宽高作为resize
Resize resize = displayOptions.getResize();
if (resize == null && displayOptions.isResizeByFixedSize()) {
if (fixedSize != null) {
resize = new Resize(fixedSize.getWidth(), fixedSize.getHeight(), viewInfo.getScaleType());
displayOptions.setResize(resize);
} else {
throw new IllegalStateException("ImageView's width and height are not fixed," +
" can not be applied with the resizeByFixedSize function");
}
}
// 如果没有设置ScaleType的话就从ImageView身上取
if (resize != null && resize.getScaleType() == null && imageViewInterface != null) {
resize.setScaleType(viewInfo.getScaleType());
}
// 检查Resize的宽高都必须大于0
if (resize != null && (resize.getWidth() == 0 || resize.getHeight() == 0)) {
throw new IllegalArgumentException("Resize width and height must be > 0");
}
// 没有设置maxSize的话,如果ImageView的宽高是的固定的就根据ImageView的宽高来作为maxSize,否则就用默认的maxSize
if (displayOptions.getMaxSize() == null) {
MaxSize maxSize = imageSizeCalculator.calculateImageMaxSize(imageViewInterface);
if (maxSize == null) {
maxSize = imageSizeCalculator.getDefaultImageMaxSize(configuration.getContext());
}
displayOptions.setMaxSize(maxSize);
}
// 检查MaxSize的宽或高大于0即可
MaxSize maxSize = displayOptions.getMaxSize();
if (maxSize != null && maxSize.getWidth() <= 0 && maxSize.getHeight() <= 0) {
throw new IllegalArgumentException("MaxSize width or height must be > 0");
}
// 没有ImageProcessor但有resize的话就需要设置一个默认的图片裁剪处理器
if (displayOptions.getImageProcessor() == null && resize != null) {
displayOptions.setImageProcessor(configuration.getResizeImageProcessor());
}
// 如果设置了全局使用低质量图片的话就强制使用低质量的图片
if (configuration.isGlobalLowQualityImage()) {
displayOptions.setLowQualityImage(true);
}
// 如果设置了全局解码质量优先
if (configuration.isGlobalInPreferQualityOverSpeed()) {
displayOptions.setInPreferQualityOverSpeed(true);
}
// 如果没有设置请求Level的话就跟据暂停下载和暂停加载功能来设置请求Level
if (displayOptions.getRequestLevel() == null) {
if (configuration.isGlobalPauseDownload()) {
displayOptions.setRequestLevel(RequestLevel.LOCAL);
displayOptions.setRequestLevelFrom(RequestLevelFrom.PAUSE_DOWNLOAD);
}
if (configuration.isGlobalPauseLoad()) {
displayOptions.setRequestLevel(RequestLevel.MEMORY);
displayOptions.setRequestLevelFrom(RequestLevelFrom.PAUSE_LOAD);
}
}
// ImageDisplayer必须得有
if (displayOptions.getImageDisplayer() == null) {
displayOptions.setImageDisplayer(configuration.getDefaultImageDisplayer());
}
// 使用过渡图片显示器的时候,如果使用了loadingImage的话就必须配合ShapeSize才行,如果没有ShapeSize就取ImageView的宽高作为ShapeSize
if (displayOptions.getImageDisplayer() instanceof TransitionImageDisplayer
&& displayOptions.getLoadingImage() != null && displayOptions.getShapeSize() == null) {
if (fixedSize != null) {
displayOptions.setShapeSize(fixedSize.getWidth(), fixedSize.getHeight());
} else {
View imageView = imageViewInterface.getSelf();
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
String errorInfo = SketchUtils.concat(
"If you use TransitionImageDisplayer and loadingImage, " +
"You must be setup ShapeSize or imageView width and height must be fixed",
". width=", SketchUtils.viewLayoutFormatted(layoutParams.width),
", height=", SketchUtils.viewLayoutFormatted(layoutParams.height));
if (SLogType.REQUEST.isEnabled()) {
SLog.d(SLogType.REQUEST, logName, "%s. viewHashCode=%s. %s",
errorInfo, Integer.toHexString(imageViewInterface.hashCode()), displayInfo.getKey());
}
throw new IllegalArgumentException(errorInfo);
}
}
// 根据URI和显示选项生成请求key
if (displayInfo.getKey() == null) {
displayInfo.setKey(SketchUtils.makeRequestKey(displayInfo.getUri(), displayOptions));
}
}
/**
* 将相关信息保存在SketchImageView中,以便在RecyclerView中恢复显示使用
*/
private void saveParams() {
DisplayParams displayParams = imageViewInterface.getDisplayParams();
if (displayParams == null) {
displayParams = new DisplayParams();
imageViewInterface.setDisplayParams(displayParams);
}
displayParams.info.copy(displayInfo);
displayParams.options.copy(displayOptions);
}
private boolean checkUri() {
if (displayInfo.getUri() == null || "".equals(displayInfo.getUri().trim())) {
if (SLogType.REQUEST.isEnabled()) {
SLog.e(SLogType.REQUEST, logName, "uri is null or empty. viewHashCode=%s",
Integer.toHexString(imageViewInterface.hashCode()));
}
Drawable drawable = null;
if (displayOptions.getErrorImage() != null) {
Context context = sketch.getConfiguration().getContext();
drawable = displayOptions.getErrorImage().getDrawable(context, imageViewInterface, displayOptions);
} else if (displayOptions.getLoadingImage() != null) {
Context context = sketch.getConfiguration().getContext();
drawable = displayOptions.getLoadingImage().getDrawable(context, imageViewInterface, displayOptions);
}
imageViewInterface.setImageDrawable(drawable);
CallbackHandler.postCallbackError(displayListener, ErrorCause.URI_NULL_OR_EMPTY, false);
return false;
}
if (displayInfo.getUriScheme() == null) {
String viewCode = Integer.toHexString(imageViewInterface.hashCode());
SLog.e(SLogType.REQUEST, logName, "unknown uri scheme: %s. viewHashCode=%s. %s",
displayInfo.getUri(), viewCode, displayInfo.getUri());
Drawable drawable = null;
if (displayOptions.getErrorImage() != null) {
Context context = sketch.getConfiguration().getContext();
drawable = displayOptions.getErrorImage().getDrawable(context, imageViewInterface, displayOptions);
} else if (displayOptions.getLoadingImage() != null) {
Context context = sketch.getConfiguration().getContext();
drawable = displayOptions.getLoadingImage().getDrawable(context, imageViewInterface, displayOptions);
}
imageViewInterface.setImageDrawable(drawable);
CallbackHandler.postCallbackError(displayListener, ErrorCause.URI_NO_SUPPORT, false);
return false;
}
return true;
}
private boolean checkMemoryCache() {
if (!displayOptions.isCacheInMemoryDisabled()) {
RefBitmap cachedRefBitmap = sketch.getConfiguration().getMemoryCache().get(displayInfo.getMemoryCacheKey());
if (cachedRefBitmap != null) {
if (!cachedRefBitmap.isRecycled()) {
// 立马标记等待使用,防止刚放入内存缓存就被挤出去回收掉
cachedRefBitmap.setIsWaitingUse(logName + ":waitingUse:fromMemory", true);
if (SLogType.REQUEST.isEnabled()) {
String viewCode = Integer.toHexString(imageViewInterface.hashCode());
SLog.i(SLogType.REQUEST, logName, "image display completed. %s. %s. viewHashCode=%s",
ImageFrom.MEMORY_CACHE.name(), cachedRefBitmap.getInfo(), viewCode);
}
RefBitmapDrawable refBitmapDrawable = new RefBitmapDrawable(cachedRefBitmap);
refBitmapDrawable.setImageFrom(ImageFrom.MEMORY_CACHE);
Drawable finalDrawable;
if (displayOptions.getShapeSize() != null || displayOptions.getImageShaper() != null) {
finalDrawable = new ShapeBitmapDrawable(sketch.getConfiguration().getContext(), refBitmapDrawable,
displayOptions.getShapeSize(), displayOptions.getImageShaper());
} else {
finalDrawable = refBitmapDrawable;
}
ImageDisplayer imageDisplayer = displayOptions.getImageDisplayer();
if (imageDisplayer != null && imageDisplayer.isAlwaysUse()) {
imageDisplayer.display(imageViewInterface, finalDrawable);
} else {
imageViewInterface.setImageDrawable(finalDrawable);
}
if (displayListener != null) {
displayListener.onCompleted(ImageFrom.MEMORY_CACHE, cachedRefBitmap.getAttrs().getMimeType());
}
cachedRefBitmap.setIsWaitingUse(logName + ":waitingUse:finish", false);
return false;
} else {
sketch.getConfiguration().getMemoryCache().remove(displayInfo.getMemoryCacheKey());
if (SLogType.REQUEST.isEnabled()) {
String viewCode = Integer.toHexString(imageViewInterface.hashCode());
SLog.e(SLogType.REQUEST, logName, "memory cache drawable recycled. %s. viewHashCode=%s",
cachedRefBitmap.getInfo(), viewCode);
}
}
}
}
return true;
}
private boolean checkRequestLevel() {
// 如果已经暂停加载的话就不再从本地或网络加载了
if (displayOptions.getRequestLevel() == RequestLevel.MEMORY) {
boolean isPauseLoad = displayOptions.getRequestLevelFrom() == RequestLevelFrom.PAUSE_LOAD;
if (SLogType.REQUEST.isEnabled()) {
SLog.w(SLogType.REQUEST, logName,
"canceled. %s. viewHashCode=%s. %s", isPauseLoad ? "pause load" : "requestLevel is memory",
Integer.toHexString(imageViewInterface.hashCode()), displayInfo.getKey());
}
Drawable loadingDrawable = null;
if (displayOptions.getLoadingImage() != null) {
Context context = sketch.getConfiguration().getContext();
loadingDrawable = displayOptions.getLoadingImage().getDrawable(context, imageViewInterface, displayOptions);
}
imageViewInterface.clearAnimation();
imageViewInterface.setImageDrawable(loadingDrawable);
CancelCause cancelCause = isPauseLoad ? CancelCause.PAUSE_LOAD : CancelCause.REQUEST_LEVEL_IS_MEMORY;
CallbackHandler.postCallbackCanceled(displayListener, cancelCause, false);
return false;
}
// 如果只从本地加载并且是网络请求并且磁盘中没有缓存就结束吧
if (displayOptions.getRequestLevel() == RequestLevel.LOCAL
&& displayInfo.getUriScheme() == UriScheme.NET
&& !sketch.getConfiguration().getDiskCache().exist(displayInfo.getDiskCacheKey())) {
boolean isPauseDownload = displayOptions.getRequestLevelFrom() == RequestLevelFrom.PAUSE_DOWNLOAD;
if (SLogType.REQUEST.isEnabled()) {
SLog.d(SLogType.REQUEST, logName,
"canceled. %s. viewHashCode=%s. %s", isPauseDownload ? "pause download" : "requestLevel is local",
Integer.toHexString(imageViewInterface.hashCode()), displayInfo.getKey());
}
// 显示暂停下载图片
Drawable drawable = null;
if (displayOptions.getPauseDownloadImage() != null) {
Context context = sketch.getConfiguration().getContext();
drawable = displayOptions.getPauseDownloadImage().getDrawable(context, imageViewInterface, displayOptions);
imageViewInterface.clearAnimation();
} else if (displayOptions.getLoadingImage() != null) {
Context context = sketch.getConfiguration().getContext();
drawable = displayOptions.getLoadingImage().getDrawable(context, imageViewInterface, displayOptions);
} else {
if (SLogType.REQUEST.isEnabled()) {
SLog.w(SLogType.REQUEST, logName, "pauseDownloadDrawable is null. viewHashCode=%s. %s",
Integer.toHexString(imageViewInterface.hashCode()), displayInfo.getKey());
}
}
imageViewInterface.setImageDrawable(drawable);
CancelCause cancelCause = isPauseDownload ? CancelCause.PAUSE_DOWNLOAD : CancelCause.REQUEST_LEVEL_IS_LOCAL;
CallbackHandler.postCallbackCanceled(displayListener, cancelCause, false);
return false;
}
return true;
}
/**
* 试图取消已经存在的请求
*
* @return DisplayRequest 非null:请求一模一样,无需取消;null:已经取消或没有已存在的请求
*/
private DisplayRequest checkRepeatRequest() {
DisplayRequest potentialRequest = SketchUtils.findDisplayRequest(imageViewInterface);
if (potentialRequest != null && !potentialRequest.isFinished()) {
if (displayInfo.getKey().equals(potentialRequest.getKey())) {
if (SLogType.REQUEST.isEnabled()) {
SLog.d(SLogType.REQUEST, logName, "repeat request. newId=%s. viewHashCode=%s",
displayInfo.getKey(), Integer.toHexString(imageViewInterface.hashCode()));
}
return potentialRequest;
} else {
if (SLogType.REQUEST.isEnabled()) {
SLog.w(SLogType.REQUEST, logName, "cancel old request. newId=%s. oldId=%s. viewHashCode=%s",
displayInfo.getKey(), potentialRequest.getKey(), Integer.toHexString(imageViewInterface.hashCode()));
}
potentialRequest.cancel(CancelCause.BE_REPLACED_ON_HELPER);
}
}
return null;
}
private DisplayRequest submitRequest() {
RequestFactory requestFactory = sketch.getConfiguration().getRequestFactory();
RequestAndViewBinder requestAndViewBinder = new RequestAndViewBinder(imageViewInterface);
DisplayRequest request = requestFactory.newDisplayRequest(
sketch, displayInfo, displayOptions, viewInfo,
requestAndViewBinder, displayListener, downloadProgressListener);
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("createRequest");
}
LoadingDrawable loadingDrawable;
StateImage loadingImage = displayOptions.getLoadingImage();
if (loadingImage != null) {
Context context = sketch.getConfiguration().getContext();
Drawable drawable = loadingImage.getDrawable(context, imageViewInterface, displayOptions);
loadingDrawable = new LoadingDrawable(drawable, request);
} else {
loadingDrawable = new LoadingDrawable(null, request);
}
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("createLoadingImage");
}
imageViewInterface.setImageDrawable(loadingDrawable);
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("setLoadingImage");
}
if (SLogType.REQUEST.isEnabled()) {
SLog.d(SLogType.REQUEST, logName, "submit request. viewHashCode=%s. %s",
Integer.toHexString(imageViewInterface.hashCode()), displayInfo.getKey());
}
request.submit();
if (SLogType.TIME.isEnabled()) {
Stopwatch.with().record("submitRequest");
}
return request;
}
}