1.简介
2.使用
3.分析
1)with()
a.get(Context context)
b.get(Activity activity)
2)load()
a.DrawableTypeRequest
b.fromString()
c.load(string)
3)into()
a)applyCenterCrop()
b)glide.buildImageViewTarget(view, transcodeClass)
c)into()
①Model(本地、网络图等) ----经过ModelLoader加载数据---->
②拿到原始数据Data ----Decoder资源解码---->
③得到解码后资源Resource ----Transform裁剪等转换操作---->
④变成TransformedResource ----图像进行Transcode转码操作---->
⑤变成TranscodedResource -------->设置到Target,即ImageView上
依赖:compile 'com.github.bumptech.glide:glide:3.7.0'
Glide.with(getApplicationContext())//目标context->决定加载图片的生命周期
.load(R.mipmap.draw_img)//图片资源
.placeholder(R.mipmap.ic_launcher)//预览图
.error(R.mipmap.ic_launcher)//加载失败展示图
.override(300,300) //指定图片的大小,避免内存浪费
.fitCenter() //缩放类型 可能不填满控件,留白
.centerCrop()//缩放类型 可能不完全显示,裁剪超出控件部分
.skipMemoryCache(true)//跳过内存缓存 默认使用内存缓存
.crossFade(500)//设置渐变式显示的时间
.diskCacheStrategy(DiskCacheStrategy.ALL)//缓存所有版本的图像
.diskCacheStrategy(DiskCacheStrategy.NONE)//跳过磁盘缓存
.diskCacheStrategy(DiskCacheStrategy.SOURCE)//只缓存原来的全分辨率的图像
.diskCacheStrategy(DiskCacheStrategy.RESULT)//只缓存最后处理过的图像
.priority(Priority.HIGH)//加载优先级
.into(imageView);//目标控件
public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(context);
}
public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static RequestManager with(android.app.Fragment fragment) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(fragment);
}
public static RequestManager with(Fragment fragment) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(fragment);
}
看到可传入的参数可以为5种类型,主要是方便绑定不同的生命周期,来控制图片的加载和销毁的时机等。
先看看第一个参数为Context的:
public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(context);
}
RequestManagerRetriever,其作用主要用于生产RequestManager:
public class RequestManagerRetriever implements Handler.Callback {
private volatile RequestManager applicationManager;
...}
我们可以把RequestManager暂时理解为处理图片加载请求的管理者。
当RequestManagerRetriever创建好了后,调用了它的get方法:
public class RequestManagerRetriever implements Handler.Callback {
public RequestManager get(Context context) {
//入参判空
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
}
//是否在主线程 类型判断
else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper) {
return get(((ContextWrapper) context).getBaseContext());
}
}
//当不满足在主线程 且 类型为Application,则调用如下方法
return getApplicationManager(context);
}
//当不满足在主线程 且 类型为Application 获取需要的RequestManager
private RequestManager getApplicationManager(Context context) {
//双重锁单例 初始化
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
//初始化RequestManager,并返回
applicationManager = new RequestManager(
context.getApplicationContext(),
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode());
}
}
}
return applicationManager;
}
...
}
上面代码描述了入参为Context的情形,再来看看入参为Activity的情形:
public class RequestManagerRetriever implements Handler.Callback {
...
public RequestManager get(Activity activity) {
//为后台线程,切版本小于11
if (Util.isOnBackgroundThread() ||
Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
//调用的get方法,就是上方讲解过的,入参为Context的get方法
return get(activity.getApplicationContext());
} else {
//下方->判断act是否销毁
assertNotDestroyed(activity);
//注意这里通过activity对象拿到fra的管理
android.app.FragmentManager fm = activity.getFragmentManager();
//通过fragmentGet获取RequestManager
return fragmentGet(activity, fm);
}
}
...
//判断activity是否销毁,销毁则抛出异常
private static void assertNotDestroyed(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
}
}
...
}
看看fragmentGet(activity, fm):
RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
//获取RequestManager
//通过这两行,可以发现RequestManagerFragment是和RequestManager绑定的,即一一对应
RequestManagerFragment current = getRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
//创建RequestManager
requestManager = new RequestManager(context,
current.getLifecycle(),
current.getRequestManagerTreeNode());
//手动绑定RequestManager和无界面的fragment,即RequestManagerFragment
current.setRequestManager(requestManager);
}
return requestManager;
}
RequestManagerFragment属于一种无界面的fragment,因为glide无法直接监听Activity的生命周期,所以选择通过其绑定RequestManager,从而去将图片加载等操作绑定到Activity的生命周期上。进入RequestManagerFragment:
/**
* can be used to start, stop and manage Glide requests started for targets the fragment or
* activity this fragment is a
*/
//官方注释很明确,提示RequestManagerFragment管理Glide请求的开始和结束
public class RequestManagerFragment extends Fragment {
//实现Lifecycle接口,
private final ActivityFragmentLifecycle lifecycle;
//调用ActivityFragmentLifecycle的方法,去监听activity的生命周期
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
}
}
看看ActivityFragmentLifecycle:
class ActivityFragmentLifecycle implements Lifecycle {
private final Set lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap());
private boolean isStarted;
private boolean isDestroyed;
...
//作用:监听activity的onStart onStop onDestroy
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
load支持多种图片来源:
看看load(String):
public DrawableTypeRequest load(String string) {
return (DrawableTypeRequest) fromString().load(string);
}
分成3部分:DrawableTypeRequest + fromString() + load(string)
继承关系如下:
先看看DrawableTypeRequest
/**
* A class for creating a load request that loads either an animated GIF drawable or a
* Bitmap drawable directly, or
* adds an ResourceTranscoder to transcode the data into a
* resource type other than a Drawable
*/
//翻译:用于创建加载请求的类,该请求加载动画GIF drawable或位图可直接绘制,或添加一个
//ResourceTranscoder来将数据转换为资源类型(Drawable除外)
public class DrawableTypeRequest
extends DrawableRequestBuilder
implements DownloadOptions {
//强制指定加载静态图片 返回BitmapTypeRequest
public BitmapTypeRequest asBitmap() {
return optionsApplier.apply(new BitmapTypeRequest(this,
streamModelLoader,fileDescriptorModelLoader, optionsApplier));
}
//强制指定加载动态gif图片 返回GifTypeRequest
public GifTypeRequest asGif() {
return optionsApplier.apply(new GifTypeRequest(this,
streamModelLoader, optionsApplier));
}
}
再看看最终的GenericRequestBuilder:
public class GenericRequestBuilder implements Cloneable {
protected final Class modelClass;
protected final Context context;
protected final Glide glide;
protected final Class transcodeClass;
private int placeholderId;//预览
private int errorId;//失败
private Priority priority = null;//优先级
private int overrideHeight = -1;//重写宽高
private int overrideWidth = -1;
protected final RequestTracker requestTracker;//请求追踪器,跟踪图片请求周期
protected final Lifecycle lifecycle;
private DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.RESULT;//缓存策略
private ChildLoadProvider loadProvider;
...
}
public DrawableTypeRequest fromString() {
return loadGeneric(String.class);
}
private DrawableTypeRequest loadGeneric(Class modelClass) {
//创建2个modelloader 用来加载model(图片资源)
ModelLoader streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
ModelLoader fileDescriptorModelLoader =
Glide.buildFileDescriptorModelLoader(modelClass, context);
...
//创建DrawableTypeRequest
//参数基本都在父类GenericRequestBuilder中
return optionsApplier.apply(
new DrawableTypeRequest(modelClass,
streamModelLoader,
fileDescriptorModelLoader,
context,
glide,
requestTracker,
lifecycle,
optionsApplier));
}
@Override
public DrawableRequestBuilder load(ModelType model) {
super.load(model);
return this;
}
进入super.load(model):
public class GenericRequestBuilder implements Cloneable {
public GenericRequestBuilder
load(ModelType model) {
//赋值操作
this.model = model;
isModelSet = true;
return this;
}
...
}
可以发现load(string)方法其实,也是在做一些初始化赋值的操作。同时拿到了图片请求的管理DrawableRequestBuilder。
@Override
public Target into(ImageView view) {
return super.into(view);
}
进入父类into():
public Target 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;
default:
// Do nothing.
}
}
//最终生成imagetarget
return into(glide.buildImageViewTarget(view, transcodeClass));
}
其最终实现操作的类有3个:
DrawableRequestBuilder
BitmapRequestBuilder
GifRequestBuilder
看看DrawableRequestBuilder的实现操作:
//第一步
@Override
void applyCenterCrop() {
centerCrop();
}
//第二步
public DrawableRequestBuilder centerCrop() {
//getDrawableCenterCrop()初始化Transformation
return transform(glide.getDrawableCenterCrop());
}
//第三步
@Override
public DrawableRequestBuilder transform
(Transformation... transformation) {
super.transform(transformation);
}
//第四步 初始化Transformation
GenericRequestBuilder
transform(
Transformation... transformations) {
isTransformationSet = true;
if (transformations.length == 1) {
transformation = transformations[0];
} else {
transformation = new MultiTransformation(transformations);
}
return this;
}
//第一步
Target buildImageViewTarget(ImageView imageView, Class transcodedClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}
//第二步
public Target buildTarget(ImageView view, Class clazz) {
//加载gif
if (GlideDrawable.class.isAssignableFrom(clazz)) {
return (Target) new GlideDrawableImageViewTarget(view);
}
//调用asbitmap的加载
else if (Bitmap.class.equals(clazz)) {
return (Target) new BitmapImageViewTarget(view);
}
//加载drawable
else if (Drawable.class.isAssignableFrom(clazz)) {
return (Target) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException("Unhandled class: " + clazz
+ ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
看看方法返回的Target类和其继承的LifecycleListener:
public interface Target extends LifecycleListener {
int SIZE_ORIGINAL = Integer.MIN_VALUE;
void onLoadStarted(Drawable placeholder);
void onLoadFailed(Exception e, Drawable errorDrawable);
void getSize(SizeReadyCallback cb);
void setRequest(Request request);
Request getRequest();
}
public interface LifecycleListener {
void onStart();
void onStop();
void onDestroy();
}
找到target实现类ImageViewTarget:
public abstract class ImageViewTarget extends
ViewTarget implements GlideAnimation.ViewAdapter {
public ImageViewTarget(ImageView view) {
super(view);
}
@Override
public Drawable getCurrentDrawable() {
return view.getDrawable();
}
@Override
public void setDrawable(Drawable drawable) {
view.setImageDrawable(drawable);
}
//显示占位图片
@Override
public void onLoadStarted(Drawable placeholder) {
view.setImageDrawable(placeholder);
}
//显示占位图片
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
view.setImageDrawable(errorDrawable);
}
//显示占位图片
@Override
public void onLoadCleared(Drawable placeholder) {
view.setImageDrawable(placeholder);
}
@Override
public void onResourceReady(Z resource, GlideAnimation super Z> glideAnimation) {
if (glideAnimation == null || !glideAnimation.animate(resource, this)) {
setResource(resource);
}
}
//抽象的setResource()
protected abstract void setResource(Z resource);
}
抽象的setResource,是因为加载的资源有多种。
可以看到抽象方法的实现类有3个:
1.BitmapImageViewTarget
public class BitmapImageViewTarget extends ImageViewTarget {
public BitmapImageViewTarget(ImageView view) {
super(view);
}
//设置bitmap
@Override
protected void setResource(Bitmap resource) {
view.setImageBitmap(resource);
}
}
2.DrawableImageViewTarget
public class DrawableImageViewTarget extends ImageViewTarget {
public DrawableImageViewTarget(ImageView view) {
super(view);
}
//加载drawable
@Override
protected void setResource(Drawable resource) {
view.setImageDrawable(resource);
}
}
3.GlideDrawableImageViewTarget
@Override
protected void setResource(GlideDrawable resource) {
view.setImageDrawable(resource);
}
现在可以知道glide.buildImageViewTarget(view, transcodeClass),是返回了target,且target内部封装了图片加载过程。
public > Y into(Y target) {
Util.assertMainThread();//必须是主线程
if (target == null) {
throw new IllegalArgumentException
("You must pass in a non null Target");
}
if (!isModelSet) {
throw new IllegalArgumentException
("You must first set a model (try #load())");
}
//创建加载图片的request,request是通过settag绑定到target的
Request previous = target.getRequest();
//对旧的已绑定的target的request,进行清空删除
if (previous != null) {
previous.clear();
requestTracker.removeRequest(previous);
previous.recycle();
}
//新建request
Request request = buildRequest(target);
//通过settag将request和target绑定
target.setRequest(request);
//设置监听
lifecycle.addListener(target);
//请求跟踪器,执行加载request请求
requestTracker.runRequest(request);
return target;
}
重点看runRequest(),执行request请求的方法:
public void runRequest(Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
进入request.begin(),查看GenericRequest类的实现:
@Override
public void begin() {
startTime = LogTime.getLogTime();
if (model == null) {
onException(null);
return;
}
status = Status.WAITING_FOR_SIZE;
//是否指定大小,比如调用过.override(300,300)
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
//计算出宽高,之后也会回到onSizeReady()方法
target.getSize(this);
}
//显示占位图片
if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished run method in " + LogTime.getElapsedMillis(startTime));
}
}
看看onSizeReady():
@Override
public void onSizeReady(int width, int height) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;
width = Math.round(sizeMultiplier * width);
height = Math.round(sizeMultiplier * height);
//拿到需要加载的原始数据,一般为图片资源的输入流。内部封装了编解码等等操作
ModelLoader modelLoader = loadProvider.getModelLoader();
//将原始数据转换成能直接用的各种数据类型
final DataFetcher dataFetcher = modelLoader.getResourceFetcher
(model, width, height);
if (dataFetcher == null) {
onException(new Exception("Failed to load model: \'" + model + "\'"));
return;
}
//拿到负责资源解码的对象
ResourceTranscoder transcoder = loadProvider.getTranscoder();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished setup for calling load in " +
LogTime.getElapsedMillis(startTime));
}
loadedFromMemoryCache = true;
//加载过程
loadStatus = engine.load(signature, width,
height, dataFetcher, loadProvider, transformation, transcoder,
priority, isMemoryCacheable, diskCacheStrategy, this);
loadedFromMemoryCache = resource != null;
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
}
进入重点加载图片的方法engine.load():
public LoadStatus load(
Key signature, int width,
int height, DataFetcher fetcher,
DataLoadProvider loadProvider,
Transformation transformation,
ResourceTranscoder transcoder,
Priority priority, boolean isMemoryCacheable,
DiskCacheStrategy diskCacheStrategy,
ResourceCallback cb) {
//是否主线程
Util.assertMainThread();
long startTime = LogTime.getLogTime();
//获取图片加载的标识 如果加载网络图片,则是图片url
final String id = fetcher.getId();
//EngineKey可以理解为glide缓存图片的key
EngineKey key = keyFactory.buildKey(id, signature,
width, height, loadProvider.getCacheDecoder(),
loadProvider.getSourceDecoder(), transformation,
loadProvider.getEncoder(),
transcoder, loadProvider.getSourceEncoder());
//从缓存尝试获取图片
EngineResource> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {//缓存有数据
cb.onResourceReady(cached);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
//缓存中无图片,判断正在使用的资源资源是否有 EngineResource为带弱引用的map
EngineResource> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
//开启新的网络加载图片
EngineJob current = jobs.get(key);
if (current != null) {
current.addCallback(cb);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
DecodeJob decodeJob = new DecodeJob(key,
width, height, fetcher, loadProvider, transformation,
transcoder, diskCacheProvider, diskCacheStrategy, priority);
EngineRunnable runnable = new EngineRunnable(engineJob,
decodeJob, priority);
jobs.put(key, engineJob);
engineJob.addCallback(cb);
engineJob.start(runnable);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}