public Target<TranscodeType> into(ImageView view) {
Util.assertMainThread();
if (view == null) {
throw new IllegalArgumentException("You must pass in a non null View");
if (!isTransformationSet && view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
applyCenterCrop();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
applyFitCenter();
break;
//$CASES-OMITTED$
default:// Do nothing.
return into(glide.buildImageViewTarget(view, transcodeClass));
public class ImageViewTargetFactory {
public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
if (GlideDrawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new GlideDrawableImageViewTarget(view);
} else if (Bitmap.class.equals(clazz)) {
return (Target<Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException("Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
GlideDrawableImageViewTarget.java 有实现LifecycleListener
//真正的加载、缓存,放在Engine中,加载好之后会回调onResourceRedy方法,回调完了就把图片设置给ImageView
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
if (!resource.isAnimated()) {
float viewRatio = view.getWidth() / (float) view.getHeight();
float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN && Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
resource = new SquaringDrawable(resource, view.getWidth());
super.onResourceReady(resource, animation);
this.resource = resource;
resource.setLoopCount(maxLoopCount);
resource.start();
//给真正的ImageView设置图片
@Override
protected void setResource(GlideDrawable resource) {
view.setImageDrawable(resource);
@Override
public void onStart() {//跟页面生命周期一致
if (resource != null) {
resource.start();//如果是Gif图片,会在这里开始动画
@Override
public void onStop() {//跟页面生命周期一致
if (resource != null) {
resource.stop();//如果是Gif图片,会在这里停止动画
}
into(ImageTarget target);
1、该方法中有创建Request对象,并把target与request绑定,由于target是实现lifeCycleListener接口,target添加到了lifeCycle中,这样在创建的空白Fragment生命周期变化时,可以拿到target的request,来控制请求的开始与暂停。
2、该方法中还有调用requestTracker.runRequest(request),里面调用了request.begin(),它会调用Engine.load(xx)方法,
先从缓存找,找不到就调用
DecodeJob.decodeFromSource()
,调用我们在GlideModule中注册时自定义的OkHttpStreamFetcher.loadData去下载图片。
3、下载完成后调用DecodeJob.decodeFromSourceData()解码,解码实际上是loadProvider.getSourceDecoder().decode(data, width, height),使用的解码器还是创建RequestManager.load()创建DrawableTypeRequest时
glide.buildTranscoder(resourceClass, transcodedClass)
创建的解码器。
4、解码代码是在EngineRunnable中,
解码成功后会调onLoadComplete(resource)
,该方法会发一条MSG_COMPLETE的消息给handler,之后一路走到回调onResourceReady的地方在onResourceReady中可以做设置图片什么的一系列操作。
5、图片尺寸
执行下载之前,会计算图片尺寸,调用ViewTarget$SizeDeterminer.getSize()方法
public void getSize(SizeReadyCallback cb) {
int currentWidth = getViewWidthOrParam();
int currentHeight = getViewHeightOrParam();
if (isSizeValid(currentWidth) && isSizeValid(currentHeight)) {
//这个onSizeReady触发GenericRequest的onSizeReady,里面又调用了modelLoader.getResourceFetcher(model, width, height);
//这个modelLoader可以是自定义的。而width、height传进去后可以作为参数传给服务端,由服务端裁剪后返回跟控件大小匹配的小图
cb.onSizeReady(currentWidth, currentHeight); } else {// We want to notify callbacks in the order they were added and we only expect one or two callbacks to // be added a time, so a List is a reasonable choice. if (!cbs.contains(cb)) { cbs.add(cb); } if (layoutListener == null) { final ViewTreeObserver observer = view.getViewTreeObserver(); layoutListener = new SizeDeterminerLayoutListener(this) observer.addOnPreDrawListener(layoutListener); } } } private int getViewWidthOrParam() { final LayoutParams layoutParams = view.getLayoutParams();if (isSizeValid(view.getWidth())) {//写死宽高或者WRAP_CONTENT,都是用控件自身的尺寸作为图片的尺寸return view.getWidth(); } else if (layoutParams != null) {return getSizeForParam(layoutParams.width, false /*isHeight*/);} else { return PENDING_SIZE; } } private boolean isSizeValid(int size) {//由此可见WRAP_CONTENT或者写死尺寸的处理是一样的 return size > 0 || size == LayoutParams.WRAP_CONTENT; }Bitmap解码:
Downsampler.decode(InputStream is, BitmapPool pool, int outWidth, int outHeight, DecodeFormat decodeFormat)
Bitmap.Config config = getConfig(is, decodeFormat);
options.inSampleSize = sampleSize;
options.inPreferredConfig = config;
BitmapFactory.decodeStream(is, null, options);
Gift解码: GifDecoder获取每一帧的图GitDrawableResource返回
GifResourceDecoder.decode()
private GifDrawableResource decode(byte[] data, int width, int height, GifHeaderParser parser, GifDecoder decoder) {
final GifHeader
header = parser.parseHeader();
if (header.getNumFrames() <= 0 || header.getStatus()
!= GifDecoder.STATUS_OK) { // If we couldn't decode the GIF, we will end up with a frame count of 0. return null;
Bitmap firstFrame = decodeFirstFrame(decoder, header, data);
if (firstFrame == null) {
return null;
Transformation<Bitmap> unitTransformation = UnitTransformation.get();
GifDrawable gifDrawable = new GifDrawable(context, provider, bitmapPool, unitTransformation, width, height, header, data, firstFrame);
return new GifDrawableResource(gifDrawable);
public Target&lt;TranscodeType&gt; into(ImageView view) { Util.assertMainThread(); if (view == null) { throw new IllegalArgumentException("You must pass in a non null V...
在接下来的几篇文章中,我们会对 Android 中常用的图片加载框架 Glide 进行分析。在本篇文章中,我们先通过介绍 Glide 的几种常用的配置方式来了解 Glide 的部分源码。后续的文中,我们会对 Glide 的源码进行更详尽的分析。
对于 Glide,相信多数 Android 开发者并不陌生,在本文中,我们不打算对其具体使用做介绍,你可以通过查看官方文档进行学习。Glide 的 API...
Glide treats LayoutParams.WRAP_CONTENT as a request for an image the size of this device's screen dimensions.
就去百度上查询了许久,大致确定自己的错误原因时因为我的ImageVie...
recyclerview notifyChange 没有效果,只有滑动一下才能显示,参考链接:CymChad
大致意思是使用了 Rx 的话确保是 observerOn 而不是 subscribeOn;并且最好不要贸然使用 Android 控件的 alpha 和 beta 版本。
requiresFadingEdge没有效果,原因是我设置了overScrollMode为 never
RecyclerView.canScrollVertically(1)的值表示是否能向上滚动,
因为Glide是一个图片加载库,所以缓存Bitmap图片的方法与其他图片格式类似。首先,您需要将Bitmap对象转换为可以加载的图片资源,例如Drawable或File。然后,您可以使用Glide的缓存功能来缓存图片。
下面是一个使用Glide缓存Bitmap图片的示例代码:
private void cacheBitmap(Bitmap bitmap) {
// Convert Bitmap to Drawable
Drawable drawable = new BitmapDrawable(getResources(), bitmap);
// Load drawable into Glide cache
Glide.with(this)
.load(drawable)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
这段代码将Bitmap对象转换为Drawable,然后使用Glide加载并缓存图片。请注意,您可以使用`diskCacheStrategy`方法来指定缓存策略。在这种情况下,我们使用`DiskCacheStrategy.ALL`来缓存图片。