@[toc]
Glide作为android中最主流的几个图片加载框架之一,是面试中问到的必不可少的一种框架。它看似简单的外表下,实则隐藏着一个庞然大物,今天我们就把块硬骨头啃上一啃~。
glide在4.15版本生命周期管理与注册机管理进行了改进,我们从4.11版本开始看,流程读懂了再研究4.15版本是如何演化的。
一行代码进行图片加载
使用glide,一行代码就可以进行图片加载,我们从主干流程出发,抽丝剥茧,揭开他的真面目吧~
val ivImage = findViewById<ImageView>(R.id.ivImage)
//
Glide.with(activity).load("").into(ivImage)
//
Glide.with(fragment).load("").into(ivImage)
//
Glide.with(view).load("").into(ivImage)
从调用看,可以把它分为3大主要流程
- with
- load
- into
一、生命周期管理
下面来看第一大流程:with
,我们以传入activity为例,正如题所示,这个方法是进行生命周期管理的
// Glide.java
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
Glide初始化
可以看到,其最终返回了一个RequestManager
对象,那么它是如何构造的呢?继续往下看
// Glide.java
private final RequestManagerRetriever requestManagerRetriever;
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
return Glide.get(context).getRequestManagerRetriever();
}
public static Glide get(@NonNull Context context) {
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
可以分析如下几点:
RequestManager
是从RequestManagerRetriever
拿到的。Glide.get(context)
方法是一个单例,最终返回Glide对象,后又调用了getRequestManagerRetriever
方法,直接返回了requestManagerRetriever
变量。看这个变量是一个
final
类型的,那么,它必然是在构造方法中初始化的。知道了这个原理,那么来看一看Glide
对象是如何new
出来的。
上面代码中可以看到调用了checkAndInitializeGlide
方法
// Glide.java
@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
if (isInitializing) {
throw new IllegalStateException(
"You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
// 调用initializeGlide方法
initializeGlide(context, generatedAppGlideModule);
isInitializing = false;
}
// Glide.java
@GuardedBy("Glide.class")
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
注意这里传入了一个GlideBuilder
对象
// Glide.java
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
// 省略了一大段代码。。。
Glide glide = builder.build(applicationContext);
// 省略了一大段代码。。。
Glide.glide = glide;
}
为了看清主干流程,这里省略了扰乱我们视线的一些代码,可以看到,最终调用了GlideBuilder#build()
// GlideBuilder.java
@NonNull
Glide build(@NonNull Context context) {
// 1. 初始化一些线程池和缓存池, 这些对象可以先记住
// 后续会明白他们都是干什么用的
if (sourceExecutor == null) {
sourceExecutor = GlideExecutor.newSourceExecutor();
}
if (diskCacheExecutor == null) {
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}
if (animationExecutor == null) {
animationExecutor = GlideExecutor.newAnimationExecutor();
}
if (memorySizeCalculator == null) {
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
if (bitmapPool == null) {
int size = memorySizeCalculator.getBitmapPoolSize();
if (size > 0) {
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
if (arrayPool == null) {
arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
}
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
// 这里对象进行图片读取和加载,我们知道初始化了Engine对象即可,不需要知道它是做什么的
if (engine == null) {
engine =
new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
GlideExperiments experiments = glideExperimentsBuilder.build();
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory, experiments);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
experiments);
}
现在知道了Glide
是在这new
出来的,并传入了一个RequestManagerRetriever
对象,这里便形成了一个小闭环,那么我们回到主线,with
方法是调用了RequestManagerRetriever#get()
从而获取到一个RequestManager
对象
@NonNull
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
// 主线程并且context不是application时
} 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&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
// 子线程或context为application时
return getApplicationManager(context);
}
RequestManager
对象的构建分为了两种情况
- 主线程,并且context不是application时:调用
get()
方法 - 子线程或context为application时:调用
getApplicationManager(context)
为什么要这样判断呢,下面重点来了,生命周期管理正是在这两个方法中进行的。如果context是application时,它的生命周期跟随app的灭亡而销毁,否则我们可以根据activity的生命周期来进行管理
RequestManager构建
1. 传入activity时
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
1)调用supportFragmentGet
方法
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
// 创建requestManager并传入current.getGlideLifecycle()
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}
2)factory是什么?我们可以看到,RequestManager
对象是通过factory.build()
创建的
// RequestManagerRetriever.java
private final RequestManagerFactory factory;
public RequestManagerRetriever(
@Nullable RequestManagerFactory factory, GlideExperiments experiments) {
// 如果不传入,那么将使用DEFAULT_FACTORY
this.factory = factory != null ? factory : DEFAULT_FACTORY;
}
// 默认的构造器
private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
3)RequestManager
对象就创建出来了,但是创建之前,还有一个fragment(SupportRequestManagerFragment
),那么这是个什么东西呢?看看它怎么获取的
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
// 1. 根据tag获取fragment
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
// 2. tag获取不到,从pendingSupportRequestManagerFragments中获取
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
// 3. 缓存中没有就直接new即可
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
// 4. 将fragment缓存
pendingSupportRequestManagerFragments.put(fm, current);
// 5. commitAllowingStateLoss调用这个方法提交
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
// 6.发送消息,讲fragmnet从缓存中移除
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
以上代码明显是创建了一个fragment
,所以生命周期管理就是靠这个fragment来进行了。我们来看看这个fragment的构造方法
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
/**
* 以下是生命周期方法
*/
@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
对象,生命周期执行时分别调用了lifecycle
中的三个方法
class ActivityFragmentLifecycle implements Lifecycle {
// 这个集合用于保存所有的listener
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
// 添加一个listener
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
// 移除一个listener
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
// start生命周期执行时
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
// stop生命周期执行时
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
// destory生命周期执行时
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
这样生命周期管理就完成了,如果一个对象需要进行生命周期管理时,只需要实现LifecycleListener
接口,并调用ActivityFragmentLifecycle#addListener()
方法,就可以自动进行生命周期管理了。
好,我们回到第1)步骤,创建requestManager时,传入了current.getGlideLifecycle()
,这个就是fragment
中的ActivityFragmentLifecycle
对象了
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
// current.getGlideLifecycle()就是下面这个方法
// SupportRequestManagerFragment.java
//
ActivityFragmentLifecycle getGlideLifecycle() {
return lifecycle;
}
通过DEFAULT_FACTORY
构建requestManager
时,lifecycle
作为了一个构造参数:
public RequestManager(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode,
@NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
// 创建网络连接监听器
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
// RequestManager实现了LifecycleListener, 所以它可以自己进行生命周期绑定
lifecycle.addListener(this);
}
// 将网络连接监听器与生命周期绑定
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
这样,当fragment
执行生命周期onStart()
时,就会调用lifecycle.onStart()
,在通过lifecycle
回调到RequestManager
中的onStart()
。生命周期管理就这样简单的完成了,同时也意味着,所有的逻辑都是从RequestManager
出发的。
RequestManager生命周期
我们来看看RequestManager
的生命周期方法
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public synchronized void onDestroy() {
targetTracker.onDestroy();
for (Target<?> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
Util.removeCallbacksOnUiThread(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
在onStart
和onStop
中分别调用了resumeRequests
和pauseRequests
public synchronized void resumeRequests() {
requestTracker.resumeRequests();
}
// RequestTracker.java
public void resumeRequests() {
isPaused = false;
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isRunning()) {
request.begin();
}
}
pendingRequests.clear();
}
public synchronized void pauseRequests() {
requestTracker.pauseRequests();
}
// RequestTracker.java
public void pauseRequests() {
isPaused = true;
for (Request request : Util.getSnapshot(requests)) {
if (request.isRunning()) {
request.pause();
pendingRequests.add(request);
}
}
}
可以看到:
onStart
时,将所有的请求进行启动,并清空等待队列;
onStop
时,将所有的请求暂停,并加入到等待队列中;
target生命周期
我们知道,当RequestManager
进入生命周期时,进行了图片加载的启动与暂停,除此之外,还有一行代码,targetTracker.onStart()
和targetTracker.onStop()
private final TargetTracker targetTracker = new TargetTracker();
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
请记住这个方法!!!Target
对象也实现了LifecycleListener
,当其它类调用RequestManager
的track
方法时,相当于也把自己加入到了生命周期管理里面。这个地方将会真正的开始第一次网络请求,请记住requestTracker.runRequest(request);
方法,我们在第三大步骤中重点讲到。
至此,RequestManager
返回给with
函数,第一个步骤就完成了。
2. 传入application时
让我们的思绪回到RequestManager
的构建,当context
是一个application
时,它将跟随app
的生命周期而执行
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
可以看到,返回了applicationManager
,通过factory构建时,传入了ApplicationLifecycle
,而并非fragment
中的,因为application不能监听页面的生命周期,所以索性都不创建fragment
了。
class ApplicationLifecycle implements Lifecycle {
@Override
public void addListener(@NonNull LifecycleListener listener) {
listener.onStart();
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
// Do nothing.
}
}
可以看到,application
很简单,在addListener
时,调用onStart
即可,remove
时不需要进行任何操作。
二、最新版本优化
明白了它的生命周期管理,那么我们看看最新版本有什么改变呢?
了解过androidx
的Lifecycle
的同学知道,它“抄袭“了Glide
框架中的思想,每个页面也创建了一个空白的fragment
,用于管理它们的生命周期。这样我们在用Glide
的时候,一个页面就会创建两个空白的fragment
,可能是出于这方面的考虑,Glide
在最新版本中进行了优化,使用了androidx
的Lifecycle
进行生命周期管理。
我们看getRetriever(activity).get(activity);
中的get
方法
// RequestManagerRetriever.java
private final LifecycleRequestManagerRetriever lifecycleRequestManagerRetriever;
public RequestManagerRetriever(
@Nullable RequestManagerFactory factory, GlideExperiments experiments) {
this.factory = factory != null ? factory : DEFAULT_FACTORY;
lifecycleRequestManagerRetriever = new LifecycleRequestManagerRetriever(this.factory);
}
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
}
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
boolean isActivityVisible = isActivityVisible(activity);
Glide glide = Glide.get(activity.getApplicationContext());
return lifecycleRequestManagerRetriever.getOrCreate(
activity,
glide,
activity.getLifecycle(),
activity.getSupportFragmentManager(),
isActivityVisible);
}
可以看到,最终调用了LifecycleRequestManagerRetriever#getOrCreate()
// LifecycleRequestManagerRetriever.java
RequestManager getOrCreate(
Context context,
Glide glide,
final Lifecycle lifecycle,
FragmentManager childFragmentManager,
boolean isParentVisible) {
Util.assertMainThread();
// 1. 缓存中通过lifecycle获取requestmanager对象
RequestManager result = getOnly(lifecycle);
// 如果缓存中没有
if (result == null) {
// 2. 创建androidx的lifecycle监听
LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);
// 3. 构建requestmanager
result =
factory.build(
glide,
glideLifecycle,
new SupportRequestManagerTreeNode(childFragmentManager),
context);
// 4. 将requestmanager对象加入到缓存
lifecycleToRequestManager.put(lifecycle, result);
glideLifecycle.addListener(
new LifecycleListener() {
@Override
public void onStart() {}
@Override
public void onStop() {}
@Override
public void onDestroy() {
// 6. 页面销毁,移除缓存
lifecycleToRequestManager.remove(lifecycle);
}
});
if (isParentVisible) {
// 5. 直接调用onstart方法
result.onStart();
}
}
return result;
}
这次在构建RequestManager
传入了一个glideLifecycle
,也就是LifecycleLifecycle
,这个是将androidx
的Lifecycle
与Glide
的Lifecycle
进行了巧妙的融合
final class LifecycleLifecycle implements Lifecycle, LifecycleObserver {
@NonNull
private final Set<LifecycleListener> lifecycleListeners = new HashSet<LifecycleListener>();
@NonNull private final androidx.lifecycle.Lifecycle lifecycle;
LifecycleLifecycle(androidx.lifecycle.Lifecycle lifecycle) {
this.lifecycle = lifecycle;
lifecycle.addObserver(this);
}
@OnLifecycleEvent(Event.ON_START)
public void onStart(@NonNull LifecycleOwner owner) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
@OnLifecycleEvent(Event.ON_STOP)
public void onStop(@NonNull LifecycleOwner owner) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
@OnLifecycleEvent(Event.ON_DESTROY)
public void onDestroy(@NonNull LifecycleOwner owner) {
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
owner.getLifecycle().removeObserver(this);
}
@Override
public void addListener(@NonNull LifecycleListener listener) {
lifecycleListeners.add(listener);
if (lifecycle.getCurrentState() == State.DESTROYED) {
listener.onDestroy();
} else if (lifecycle.getCurrentState().isAtLeast(State.STARTED)) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
}
我们看到,它创建了一个androidx
的Lifecycle
,然后自己实现LifecycleObserver
并传入到Lifecycle
,以作为一个观察者来监听页面的生命周期变化。
与空白fragment
不同的是,这里在addListener
的时候判断页面状态,如果是可见状态,那么直接调用listener.onStart()
,然后回调到RequestManager
的onStart()
。
兼容
众所周知,android
中的Lifecycle
只有androidx
里面有,如果传入Activity
或android.app.fragment
,是不能监听生命周期的,这时,还会走进以前的方法,只是被标记为了过时。
// 传入android.app.Fragment
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public RequestManager get(@NonNull android.app.Fragment fragment) {
if (fragment.getActivity() == null) {
throw new IllegalArgumentException(
"You cannot start a load on a fragment before it is attached");
}
if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return get(fragment.getActivity().getApplicationContext());
} else {
if (fragment.getActivity() != null) {
frameWaiter.registerSelf(fragment.getActivity());
}
android.app.FragmentManager fm = fragment.getChildFragmentManager();
return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
}
}
这里就一目了然了吧,又调用了fragmentGet
方法创建一个空白的fragment
,这样兼容也就完成了。
思考
看到这里,面试中常见的两个问题你已经搞懂了,不妨自己试着回答一下
Glide如何进行生命周期管理?
使用Glide为什么有时候会出现内存溢出 or 内存泄漏?