Android开发Glide源码解析

释放双眼,带上耳机,听听看~!

2.看下Glide.with(this)方法

@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}

看下getRetriever(activity).get(activity)方法

 @NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
Preconditions.checkNotNull(context, "You cannot start a load on a not yet attached View or a Fragment where getActivity() returns null (which usually occurs when getActivity() is called before the Fragment is attached or after the Fragment is destroyed).");
return get(context).getRequestManagerRetriever();
}

看下get(context).getRequestManagerRetriever()方法

 @NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
return this.requestManagerRetriever;//requestManagerRetriever的作用是生产requestManager,requestManager的作用是管理图片请求
}

看下 getRetriever(activity).get(activity)的get(activity)方法

@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) { //如果地后台线程,context用getApplicationContext()
return this.get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
androidx.fragment.app.FragmentManager fm = activity.getSupportFragmentManager();
return this.supportFragmentGet(activity, fm, (Fragment)null);
}
}

看下this.get(activity.getApplicationContext())方法

@NonNull
public RequestManager get(@NonNull Context context) {
if (context == null) { //context不能为null
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else {
if (Util.isOnMainThread() && !(context instanceof Application)) { //如果在主线程,context不是ApplicationContext,就判断context是否是FragmentActivity,Activity,ContextWrapper
if (context instanceof FragmentActivity) {
return this.get((FragmentActivity)context);
}
if (context instanceof Activity) {
return this.get((Activity)context);
}
if (context instanceof ContextWrapper) {
return this.get(((ContextWrapper)context).getBaseContext());
}
}
return this.getApplicationManager(context);
}
}

看下his.getApplicationManager(context)方法

   @NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
if (this.applicationManager == null) {
synchronized(this) {
if (this.applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
this.applicationManager = this.factory.build(glide, new ApplicationLifecycle(), new EmptyRequestManagerTreeNode(), context.getApplicationContext());
}
}
}
return this.applicationManager;  //单例返回RequestManager
}

看下this.supportFragmentGet(activity, fm, (Fragment)null)方法

@NonNull
private RequestManager supportFragmentGet(@NonNull Context context, @NonNull androidx.fragment.app.FragmentManager fm, @Nullable Fragment parentHint) {
SupportRequestManagerFragment current = this.getSupportRequestManagerFragment(fm, parentHint);//SupportRequestManagerFragment,添加管理没有界面,空的Fragement,作用是来监听Activity的生命周期
RequestManager requestManager = current.getRequestManager();//RequestManager 还可以管理对象的构造,还可以控制Glide中图片请求的各种方法,还可以监听整个组件的生命周期,根据生命周期,对图片进行相应的操作
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager = this.factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);//将SupportRequestManagerFragment和RequestManager进行绑定,作用是将监听Activity生命周期和图片的加载这两个事情绑定在一起,绑定时候的关系是一对一
}

看下SupportRequestManagerFragment 类

	public class SupportRequestManagerFragment extends Fragment {
private static final String TAG = "SupportRMFragment";
private final ActivityFragmentLifecycle lifecycle;
.
.
.
}

看下ActivityFragmentLifecycle类

class ActivityFragmentLifecycle implements Lifecycle { //监听生命周期的,然后回调
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}                                                           .                               .
}

看下load(@Nullable String string)方法

  @Override
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}

看下asDrawable(),跟踪源码到RequestBuilder as方法

 @NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);//初始化属性,RequestBuilder通用类,可以处理通用资源类型的设置选项和启动负载。
}

看下into(@NonNull ImageView view)方法

public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
Util.assertMainThread(); //判断是否是在主线程,Android中所有的UI操作,必须要在主线程
Preconditions.checkNotNull(view);//判断view是否为null
RequestOptions requestOptions = this.requestOptions; //提供独立于类型的选项,以使用Glide自定义负载
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
//克隆此方法,以便如果我们使用此RequestBuilder加载到View中,然后
// 到另一个目标中,我们不会保留基于先前目标应用的转换
// 视图的比例类型
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions = requestOptions.clone().optionalCenterCrop();//属性的赋值操作
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions = requestOptions.clone().optionalFitCenter();
break;
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case CENTER:
case MATRIX:
default:
// Do nothing.
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions); //通过工厂模式返回ViewTarget实例
}

看下buildImageViewTarget(view, transcodeClass)方法

  @NonNull
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}

看下imageViewTargetFactory.buildTarget(imageView, transcodeClass)方法

@NonNull
@SuppressWarnings("unchecked")
public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
@NonNull Class<Z> clazz) {
if (Bitmap.class.equals(clazz)) { //通过工厂模式返回BitmapImageViewTarget实例或者DrawableImageViewTarget实例,工厂模式和策略模式的不同点就是,工厂模式侧重于对象,策略模式侧重于方法
return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
}

看下BitmapImageViewTarget类

public class BitmapImageViewTarget extends ImageViewTarget<Bitmap> {}

看下ImageViewTarget的onLoadStarted(@Nullable Drawable placeholder)方法

  @Override
public void onLoadStarted(@Nullable Drawable placeholder) {
super.onLoadStarted(placeholder);
setResourceInternal(null);
setDrawable(placeholder);
}

看下 setResourceInternal(null);方法源码,跟踪到

 protected abstract void setResource(@Nullable Z resource); //这里为什么要设置成抽象方法,因为设置图片的来源有多种
@Override
protected void setResource(Bitmap resource) { //setResource方法的实现(它的实现还有参数是Drawable和T resource)
view.setImageBitmap(resource);//就是ANdroid原生方法
}

看下 setDrawable(placeholder)方法

 @Override
public void setDrawable(Drawable drawable) {
view.setImageDrawable(drawable);//Android的原生设置图片的操作
}

看下 into(glideContext.buildImageViewTarget(view, transcodeClass), /targetListener=/ null,requestOptions)

  private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
@NonNull RequestOptions options) {
Util.assertMainThread();
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
options = options.autoClone();
Request request = buildRequest(target, targetListener, options);
Request previous = target.getRequest();//获取到旧的Request,把旧的Request删除了,才能绑定新的Request
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}

看下request.recycle()方法

@Override
public void recycle() {
assertNotCallingCallbacks();
context = null;
glideContext = null;
model = null;
transcodeClass = null;
requestOptions = null;
overrideWidth = -1;
overrideHeight = -1;
target = null;
requestListener = null;
targetListener = null;
requestCoordinator = null;
animationFactory = null;
loadStatus = null;
errorDrawable = null;
placeholderDrawable = null;
fallbackDrawable = null;
width = -1;
height = -1;
POOL.release(this);//移除,不保留
}

看下target.setRequest(request)方法

  @Override
public void setRequest(@Nullable Request request) {
setTag(request); //设置Tag,将request和图片绑定在一起,可以防止图片错位
}

看下requestManager.track(target, request)方法

 public void runRequest(@NonNull Request request) {
requests.add(request); //Set集合里添加request
if (!isPaused) { //没有正在进行的请求
request.begin();
} else { //有正在进行的请求
pendingRequests.add(request);
}
}

看下 request.begin()方法

  @Override
public void begin() {
.
.
.
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());//设置图片,添加占位图
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished run method in " + LogTime.getElapsedMillis(startTime));
}
}

看下target.getSize(this)方法

  @CallSuper
@Override
public void getSize(@NonNull SizeReadyCallback cb) {
sizeDeterminer.getSize(cb);
}

看下sizeDeterminer.getSize(cb)方法

  void getSize(@NonNull SizeReadyCallback cb) {
int currentWidth = getTargetWidth();
int currentHeight = getTargetHeight();//获取宽和高
if (isViewStateAndSizeValid(currentWidth, currentHeight)) {
cb.onSizeReady(currentWidth, currentHeight);
return;
}
// 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) {
ViewTreeObserver observer = view.getViewTreeObserver();
layoutListener = new SizeDeterminerLayoutListener(this);
observer.addOnPreDrawListener(layoutListener);//当前view还没有被测量完毕,这时候它就会添加到ViewTreeObserver当中,来进行事件的监听
}
}

看下Engine的load方法

public <R> LoadStatus load(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class<?> resourceClass,
Class<R> transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map<Class<?>, Transformation<?>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb) {
Util.assertMainThread();
long startTime = LogTime.getLogTime();
EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
resourceClass, transcodeClass, options); //决定EngineKey的参数很多,比如不同的宽高就有不同的key,EngineKey是Glide缓存的key,EngineKey中实现了quals(Object o)和hashCode()方法,保证了参数一样,才会被认为是同一个EngineKey对象
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);//从正在使用的图片资源中获取
if (active != null) {
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);//从缓存获取
if (cached != null) {
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
current.addCallback(cb);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current); //加载图片,先看下正在使用图片中有没有,没有就从缓存里去取,缓存也没有就创建runningable去加载
}

看下 loadFromCache(key, isMemoryCacheable方法

  private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
if (!isMemoryCacheable) { //isMemoryCacheable的值是设置SkipMemoryCatch(false)时设置的,Glide默认开始内存缓存
return null;
}
EngineResource<?> cached = getEngineResourceFromCache(key);
if (cached != null) {
cached.acquire();
activeResources.activate(key, cached);
}
return cached;
}

看下getEngineResourceFromCache(key)方法

 private EngineResource<?> getEngineResourceFromCache(Key key) {
Resource<?> cached = cache.remove(key);//当从内存缓存中获取到了图片,就会从内存缓存中移除
.
.
.
}

看下loadFromActiveResources(key, isMemoryCacheable)

 @Nullable
private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {
if (!isMemoryCacheable) {
return null;
}
EngineResource<?> active = activeResources.get(key);
if (active != null) {
active.acquire();
}
return active;
}

看下activeResources.get(key)方法

 @Nullable
EngineResource<?> get(Key key) {
ResourceWeakReference activeRef = activeEngineResources.get(key);//保证图片资源不会被LRU算法回收
if (activeRef == null) {
return null;
}
EngineResource<?> active = activeRef.get();
if (active == null) {
cleanupActiveReference(activeRef);
}
return active;
}

看下 cb.onResourceReady(active, DataSource.MEMORY_CACHE)方法,实现在EngineJob类中

 @Override
public void onResourceReady(Resource<R> resource, DataSource dataSource) {
this.resource = resource;
this.dataSource = dataSource;
MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}

看下MAIN_THREAD_HANDLER这个Handler

private static final Handler MAIN_THREAD_HANDLER =
new Handler(Looper.getMainLooper(), new MainThreadCallback());

看下MainThreadCallback这个类

  private static class MainThreadCallback implements Handler.Callback {
@Synthetic
@SuppressWarnings("WeakerAccess")
MainThreadCallback() { }
@Override
public boolean handleMessage(Message message) {
EngineJob<?> job = (EngineJob<?>) message.obj;
switch (message.what) {
case MSG_COMPLETE:
job.handleResultOnMainThread();//会在主线程进行回调
break;
case MSG_EXCEPTION:
job.handleExceptionOnMainThread();
break;
case MSG_CANCELLED:
job.handleCancelledOnMainThread();
break;
default:
throw new IllegalStateException("Unrecognized message: " + message.what);
}
return true;
}
}
}

看下 job.handleResultOnMainThread()方法

 @Synthetic
void handleResultOnMainThread() {
stateVerifier.throwIfRecycled();
if (isCancelled) {//如果任务取消,就回收资源
resource.recycle();
release(false /*isRemovedFromQueue*/);
return;
} else if (cbs.isEmpty()) {
throw new IllegalStateException("Received a resource without any callbacks to notify");
} else if (hasResource) {
throw new IllegalStateException("Already have resource");
}
engineResource = engineResourceFactory.build(resource, isCacheable);//通过engineResourceFactory工厂类创建EngineResource这个包含图片资源的对象  
hasResource = true;
engineResource.acquire();
listener.onEngineJobComplete(this, key, engineResource);
for (int i = 0, size = cbs.size(); i < size; i++) {
ResourceCallback cb = cbs.get(i);
if (!isInIgnoredCallbacks(cb)) {
engineResource.acquire();
cb.onResourceReady(engineResource, dataSource);
}
}
engineResource.release();
release(false /*isRemovedFromQueue*/);
}

看下listener.onEngineJobComplete(this, key, engineResource)方法

@Override
public void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
Util.assertMainThread();
// A null resource indicates that the load failed, usually due to an exception.
if (resource != null) {
resource.setResourceListener(key, this);
if (resource.isCacheable()) {
activeResources.activate(key, resource);
}
}
jobs.removeIfCurrent(key, engineJob);
}

看下 activeResources.activate(key, resource)方法

void activate(Key key, EngineResource<?> resource) {
ResourceWeakReference toPut =
new ResourceWeakReference(
key,
resource,
getReferenceQueue(),
isActiveResourceRetentionAllowed);
ResourceWeakReference removed = activeEngineResources.put(key, toPut);//代表缓存的写入,写入的是弱引用的缓存
if (removed != null) {
removed.reset();
}
}

看下 engineResource.acquire()方法

  void acquire() {//记录图片被引用的次数
if (isRecycled) {
throw new IllegalStateException("Cannot acquire a recycled resource");
}
if (!Looper.getMainLooper().equals(Looper.myLooper())) {
throw new IllegalThreadStateException("Must call acquire on the main thread");
}
++acquired;//如果acquired>0表示有图片引用,应该放到activeEngineResources弱引用缓存中
}

看下 engineResource.release()方法

void release() {
if (acquired <= 0) {
throw new IllegalStateException("Cannot release a recycled or not yet acquired resource");
}
if (!Looper.getMainLooper().equals(Looper.myLooper())) {
throw new IllegalThreadStateException("Must call release on the main thread");
}
if (--acquired == 0) {//表示图片在使用的
listener.onResourceReleased(key, this);
}
}

看下listener.onResourceReleased(key, this)方法

 @Override
public void onResourceReleased(Key cacheKey, EngineResource<?> resource) {
Util.assertMainThread();
activeResources.deactivate(cacheKey);//从缓存中删除图片
if (resource.isCacheable()) {
cache.put(cacheKey, resource);//加入到LRUCatch缓存中
} else {
resourceRecycler.recycle(resource);
}
}

人已赞赏
Android文章

Android开发ButterKnife源码解析

2021-2-1 22:39:53

Android文章

Android开发okhttp源码分析

2021-2-1 23:22:22

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索