基本使用:
依赖:
implementation 'com.github.bumptech.glide:glide:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
使用:
//Glide3中的许多配置选项转移到了RequestOptions中
RequestOptions options = new RequestOptions();
options.placeholder(R.drawable.ic_launcher_background)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(false)
.override(Target.SIZE_ORIGINAL);
//Glide调用链中的类型转化:
Glide //Glide
.with(this) //RequsetManager
.load(url) //RequestBuilder<Drawable>
.apply(options) //RequestBuilder<Drawable>
.into(target); //Target<Drawable>
Glide的成员变量:
public class Glide implements ComponentCallbacks2 {
private static volatile Glide glide;
private static volatile boolean isInitializing;
//远程请求图片的核心类,同时也管理一些缓存
private final Engine engine;
private final BitmapPool bitmapPool;
private final MemoryCache memoryCache;
private final GlideContext glideContext;
private final Registry registry;
private final ArrayPool arrayPool;
//专门用来产生RequestManager,可以理解为RequestManagerFactory
private final RequestManagerRetriever requestManagerRetriever;
private final ConnectivityMonitorFactory connectivityMonitorFactory;
private final List<RequestManager> managers = new ArrayList<>();
private final RequestOptionsFactory defaultRequestOptionsFactory;
private MemoryCategory memoryCategory = MemoryCategory.NORMAL;
}
Glide.with
public class Glide implements ComponentCallbacks2 {
//requestManagerRetriever一般都用GlideBuilder里默认生成的
private final RequestManagerRetriever requestManagerRetriever;
public static RequestManager with(Context context){
//Glide把生成RequestManager的任务都交给了RequestManagerRetriever:
return getRetriever(context).get(context);
}
//其他with方法都是类似的写法,略
public static RequestManager with(Activity activity);
public static RequestManager with(FragmentActivity activity);
public static RequestManager with(Fragment fragment);
public static RequestManager with(android.app.Fragment fragment);
public static RequestManager with(View view);
private static RequestManagerRetriever getRetriever(Context context) {
return Glide.get(context).getRequestManagerRetriever();
}
}
RequestManagerRetriever
public class RequestManagerRetriever implements Handler.Callback {
//全局的RequestManager,如果with(Context)的参数传了Application就会返回这个RequestManager单例
private volatile RequestManager applicationManager;
//1.获取全局的RequestManager单例;
private RequestManager getApplicationManager(Context context) {
return applicationManager //双重检查锁单例,略
}
//2.获取Fragment和FragmentActivity的RequestManager
private RequestManager supportFragmentGet(Context context,
FragmentManager fm,Fragment parentHint,boolean isParentVisible);
//3.获取android.app.Fragment和Activity的RequestManager
private RequestManager fragmentGet(Context context,android.app.FragmentManager fm,
android.app.Fragment parentHint,boolean isParentVisible);
//以下是伪代码:根据参数类型不同调用上面三个方法生成RequestManager
public RequestManager get(xxx) {
//在子线程或是Application返回全局的RequestManager单例
if (Util.isOnBackgroundThread() || xxx instanceof Application) {
return getApplicationContext());
}
//原生android.appfragment调用fragmentGet
else if(xxx instanceof android.app.Fragment fragment){
android.app.FragmentManager fm = fragment.getChildFragmentManager();
return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
//原生Activity调用fragmentGet
else if(xxx instanceof Activity){
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null, isActivityVisible(activity));
}
//兼容Fragment调用supportFragmentGet
else if(xxx instanceof Fragment) { //androidx.fragment.app.Fragment
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
//兼容FragmentActivity调用supportFragmentGet
else if(xxx instanceof FragmentActivity) { //androidx.fragment.app.FragmentActivity
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, null, isActivityVisible(activity));
}
//xxx 附着在上面的哪个类,就调哪个类相应的方法创建相应的RequestManager
else if(xxx instanceof View) {
...
}
}
}
构造RequestManager传入Activity或Fragment等生命周期对象的目的是,在这些生命周期对象销毁时,停止加载图片
Glide是如何跟踪Activity或者Fragment的生命周期的:
从supportFragmentGet方法看起:
//注意这里传入了一个FragmentManager对象
//这个方法会给当前页面的FragmentManager添加一个不可见的Fragment,通过这个Fragment来管理一次请求的生命周期
RequestManager supportFragmentGet(Context context, FragmentManager fm,....) {
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//这里创建了一个不可见的Fragment;
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
看下这个不可见的Fragment:
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
//创建这个Fragment的时候新建一个生命周期对象给它
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
}
ActivityFragmentLifecycle 中又可以注册很多监听器:
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
public void addListener(@NonNull LifecycleListener listener);
}
这就是Glide跟踪当前页面生命周期的原理
RequestManager
public class RequestManager implements LifecycleListener, ... {
protected final Glide glide;
final Lifecycle lifecycle;
//跟踪一个request的start,stop,Destory等状态
private final RequestTracker requestTracker;
//Request的配置选项
private RequestOptions requestOptions;
//加载图片的方法
RequestBuilder<Drawable> load(@Nullable Bitmap bitmap);
RequestBuilder<Drawable> load(@Nullable Drawable drawable);
RequestBuilder<Drawable> load(@Nullable String string);
RequestBuilder<Drawable> load(@Nullable Uri uri);
RequestBuilder<Drawable> load(@Nullable File file);
RequestBuilder<Drawable> load(@RawRes @DrawableRes @Nullable Integer resourceId);
RequestBuilder<Drawable> load(@Nullable URL url);
RequestBuilder<Drawable> load(@Nullable byte[] model);
RequestBuilder<Drawable> load(@Nullable Object model);
RequestBuilder<File> downloadOnly();
RequestBuilder<File> download(@Nullable Object model)
//生命周期回调,去控制Request要不要继续进行
public synchronized void onStart();
public synchronized void onStop();
public synchronized void onDestroy();
}
RequestBuilder
Glide最后一步会一般调用RequestBuilder的into方法,它和一般的Builder不同,并不能通过build方法创建Request对象
public class RequestBuilder<TranscodeType> {
private final Glide glide;
private final RequestManager requestManager;
public RequestBuilder<TranscodeType> apply(BaseRequestOptions<?> requestOptions);
public RequestBuilder<TranscodeType> listener(RequestListener<TranscodeType> requestListener);
public RequestBuilder<TranscodeType> error(RequestBuilder<TranscodeType> errorBuilder);
//into----------------------------------------------------------------------------------------------------
public ViewTarget<ImageView, TranscodeType> into(ImageView view) {
Util.assertMainThread(); //保证在主线程
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
...
default:
//可以看到ImageView最后也被转化为一个Target,ImageViewTarget是专门为ImageView服务的一个Target
return into(glideContext.buildImageViewTarget(view, transcodeClass),
null,requestOptions,Executors.mainThreadExecutor());
}
//
public <Y extends Target<TranscodeType>> Y into(Y target);
//所有的into方法都调用了这个方法
private <Y extends Target<TranscodeType>> Y into(Y target,RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,Executor callbackExecutor) {
//构建Request所用的buildRequest是私有方法,不提供给外部使用
Request request = buildRequest(target, targetListener, options, callbackExecutor);
requestManager.clear(target); //untrack这个Target
target.setRequest(request); //Target绑定到这个Request
//里面实际上调用了request.begin(),并开始跟踪这个Request的状态,
requestManager.track(target, request);
return target;
}
}
//className = RequestManager
synchronized void track(Target<?> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request); //调用了request.begin();
}
上面又涉及到了两个对象,分别是Target和Request
Target:
Target是一个生命周期回调接口
public interface Target<R> extends LifecycleListener {
void onLoadStarted(Drawable placeholder);
void onLoadFailed(Drawable errorDrawable);
void onResourceReady(R resource, Transition<? super R> transition);
void setRequest(Request request);
Request getRequest();
...
}
Request:
public interface Request {
void begin();
void clear();
void pause();
boolean isRunning();
boolean isComplete();
boolean isCleared();
boolean isEquivalentTo(Request other);
}
Request又有多种实现,以最简单的SingleRequest为例:
public final class SingleRequest<R> implements Request, SizeReadyCallback, ResourceCallback {
private final Context context;
private final Target<R> target;
private volatile Engine engine;
private Status status;
private Resource<R> resource;
private Drawable errorDrawable;
private Drawable placeholderDrawable;
public void begin() {
synchronized (requestLock) {
...
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
//如果在某个Request完成之后,重新启动了这个Request(比如notifyDataSetChanged)
//Glide会把同样的图片加载到同样的View上,这样就不需要重新获取宽高,就直接返回结果resource
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
//把状态修改为等待获取长宽
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE) && canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}
//长和宽获取到才去真正地执行图片加载过程
public void onSizeReady(int width, int height) {
...
//图片加载的逻辑转移到了Engine中:
loadStatus = engine.load(....)
}
//根据结果执行Target回调方法
public void onResourceReady(Resource<?> resource, DataSource dataSource) {
synchronized (requestLock) {
if (resource == null) {
...
target.onLoadFailed();
}
target.onResourceReady(resource.get(), animation);
}
}
}
private enum Status {
/** Created but not yet running. */
PENDING,
/** In the process of fetching media. */
RUNNING,
/** Waiting for a callback given to the Target to be called to determine target dimensions. */
WAITING_FOR_SIZE,
/** Finished loading media successfully. */
COMPLETE,
/** Failed to load media, may be restarted. */
FAILED,
/** Cleared by the user with a placeholder set, may be restarted. */
CLEARED,
}
由上面的代码可以看到,Request执行begin方法并不会马上创建一个网络请求,而是要等待获取到目标图片的宽和高之后才创建网络请求
Engine
public class Engine implements ... {
//一个远程Request会创建一个EngineJob,这些EngineJob都缓存在这里
//当一个Job 完成 或 取消,这个Job就会从Jobs中移除
private final Jobs jobs;
private final EngineJobFactory engineJobFactory;
private final EngineKeyFactory keyFactory;
public <R> LoadStatus load(...) {
//通过很多参数生成一个Key
EngineKey key =keyFactory.buildKey(model,signature,width,height,transformations,
resourceClass,transcodeClass,options);
//这个就是我们要请求的资源文件
EngineResource<?> memoryResource;
synchronized (this) {
//先试图从缓存中获取图片资源
memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
//缓存中没有,只能通过请求获取远程资源
if (memoryResource == null) {
return waitForExistingOrStartNewJob(...);
}
}
return null;
}
private <R> LoadStatus waitForExistingOrStartNewJob(...){
//先查看Jobs池中这个任务是不是已经在执行了
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
//发现Jobs池里已经有这个任务了,就简单地为这个任务添加一个回调接口,等任务完成
current.addCallback(cb, callbackExecutor);
return new LoadStatus(cb, current);
}
EngineJob<R> engineJob = engineJobFactory.build(key,...);
DecodeJob<R> decodeJob = decodeJobFactory.build(...);
jobs.put(key, engineJob);
//开始执行这个Job
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
//EngineJob成功完成了,把获取到的资源缓存,并从活动的任务池Jobs中移除任务
public synchronized void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
if (resource != null && resource.isMemoryCacheable()) {
activeResources.activate(key, resource);
}
jobs.removeIfCurrent(key, engineJob);
}
//任务取消的回调
public synchronized void onEngineJobCancelled(EngineJob<?> engineJob, Key key) {
jobs.removeIfCurrent(key, engineJob);
}
}
EngineJob
class EngineJob<R> implements DecodeJob.Callback<R>, Poolable {
private final GlideExecutor diskCacheExecutor;
private final GlideExecutor sourceExecutor;
private final GlideExecutor sourceUnlimitedExecutor;
private Resource<?> resource;
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
//挑选一个线程池去执行这个任务
GlideExecutor executor = decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
executor.execute(decodeJob);
}
}
DecodeJob
class DecodeJob<R> implements Runnable,...{
public void run() {
DataFetcher<?> localFetcher = currentFetcher;
runWrapped();
}
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator(); //获取一个数据源,从这里就可能会获取一个远程数据源
runGenerators();
break;
...
}
}
private DataFetcherGenerator getNextGenerator() {
switch (stage) {
...
case SOURCE: //数据源不在本地,需要网络获取
return new SourceGenerator(decodeHelper, this);
....
}
}
}