本文通过在字节面试遇到的问题总结而出,如有不对的地方,请及时批评指正。篇幅较长,请耐心阅读。如果您想了解其他框架源码,欢迎评论区留言!
篇幅较长,请耐心阅读[玫瑰]
Glide是一个优秀的图片加载框架,支持多种数据源,功能强大,性能高。如图所示:
1.在build.gradle中添加glide引用
implementation 'com.github.bumptech.glide:glide:4.12.0'
2.使用glide加载图片
Glide.with(this).load(BASE_PIC_URL).into(img_user)
Glide使用了单例设计模式,通过双重校验锁机制不仅保证了Glide对象的全局单例,而且解决了多线程环境下的并发安全问题。
Glide内部的创建RequestManager对象时使用了工厂设计模式,通过定义RequestManagerFactory抽象接口,让其子类创建RequestManager对象,隐藏其内部创建逻辑。
Glide使用了静态类GlideBuilder构建Glide对象,将Glide的各种属性封装到GlideBuilder中,根据不同的属性设置构建不同功能的Glide对象。简化Glide的构建过程。
1 .Glide使用With方法传入所需要的上下文,主线程中一般传context,fragment,activity来实现对生命周期的绑定。
public static RequestManager with(@NonNull Context context)
public static RequestManager with(@NonNull Activity activity)
public static RequestManager with(@NonNull Fragment fragment)
public static RequestManager with(@NonNull FragmentActivity activity)
2 .下面以activity为例,参数传入activity。
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
3 .通过调用RequestManagerRetriever的get方法,传入activity参数返回RequestManager对象。RequestManager主要负责管理Glide的请求和启动。
@NonNull
public RequestManager get(@NonNull Activity activity) {
//判断是否是后台线程
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else if (activity instanceof FragmentActivity) {
return get((FragmentActivity) activity);
} else {
//判断当前activity没有被销毁,否则抛出异常
assertNotDestroyed(activity);
frameWaiter.registerSelf(activity);
//获取activity中的FragmentManager
android.app.FragmentManager fm = activity.getFragmentManager();
//通过fragmentGet方法 ,创建并返回 RequestManager
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
RequestManagerRetriever的get方法中根据传入的参数不同,使用Util.isOnBackgroundThread判断子线程和主线程分别进行不同的处理。主线程中最终都是调用fragmentGet方法。注意,由于这里的参数是activity,获取的是fragmentManager,如果传入的是fragment,则获取的childFragmentManager.
4 .fragmentGet方法主要是通过RequestManagerFragment来获取RequestManager,如果没有获取到,则通过工厂模式进行创建。同时传入fragment的getGlideLifecycle。这个lifecycle是重点,需要注意。
private RequestManager fragmentGet(
@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//通过fragmentManager获取RequestManagerFragment
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
//获取RequestManagerFragment中的requestManager
RequestManager requestManager = current.getRequestManager();
//判断requestManager
if (requestManager == null) {
//如果requestManager为空,则通过工厂设计模式创建出requestManager
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//如果activity显示出来,则执行requestManager的onStart方法
if (isParentVisible) {
requestManager.onStart();
}
current.setRequestManager(requestManager);
}
return requestManager;
}
5 .创建RequestManagerFragment,这里创建一个空白页面的RequestManagerFragment并且绑定到当前activity中。
@NonNull
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
//通过tag获取fragmentManager中保存的fragment
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//如果获取不到,则进一步通过 pendingRequestManagerFragments Map中获取
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//如果还是获取不到,则进行创建
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
//同时保存到map中
pendingRequestManagerFragments.put(fm, current);
//然后添加到当前activity中
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//将这个添加动作通过handler发送给系统处理
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
6 .RequestManagerFragment的构造函数创建了ActivityFragmentLifecycle用来监听RequestManagerFragment的生命周期 onStart(),onStop(),onDestroy() 。
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
public SupportRequestManagerFragment(@NonNull 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();
}
最后在fragmentGet方法中将ActivityFragmentLifecycle通过工厂设计模式传给RequestManager并返回。
7 .ActivityFragmentLifecycle继承于Lifecycle接口。
@Override
public void addListener(@NonNull LifecycleListener listener) {
//所有的监听者都添加监听
lifecycleListeners.add(listener);
//根据不同的生命周期进行处理
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
//移除所有监听
lifecycleListeners.remove(listener);
}
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();
}
}
8 .RequestManager拿到这个lifecycle,进行绑定监听RequestManagerFragment生命周期。
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;
..)
...........................
//判断是否是后台线程
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
//添加lifecycle监听
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
..............
}
9 .通过生命周期的绑定处理对应的业务逻辑和资源释放等功能。
public synchronized void onStart() {
//开始请求
resumeRequests();
targetTracker.onStart();
}
@Override
public synchronized void onStop() {
//开始停止
pauseRequests();
targetTracker.onStop();
}
@Override
public synchronized void onDestroy() {
targetTracker.onDestroy();
//释放资源
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
Util.removeCallbacksOnUiThread(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
总结如下图所示:
Glide在主线程中使用时,通过创建一个空白的fragment添加到当前Activity/Fragment中,用来监听当前页面的生命周期变化,进行图片的显示或资源的释放。
1 . Glide在子线程中使用只能传入applicationContext。
public static RequestManager with(@NonNull Context context)
2 .通过调用RequestManagerRetriever的get方法,传入activity参数返回RequestManager对象。RequestManager主要负责管理Glide的请求和启动。
public RequestManager get(@NonNull 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
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
//子线程返回applicationManager
return getApplicationManager(context);
}
3 .在getApplicationManager方法中通过双重校验锁的单例方式返回applicationManager,applicationManager的创建使用了工厂设计模式,隐藏了applicationManager的内部创建细节。
@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;
}
4 .getApplicationManager创建applicationManager时传入了ApplicationLifecycle作为生命周期监听。
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;
.............
//如果是子线程,通过使用Handler切换到主线程
if (Util.isOnBackgroundThread()) {
Util.postOnUiThread(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
................
}
5 .RequestManager拿到这个lifecycle,使用Handler切换到主线程进行绑定监听Application生命周期。
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
};
6 .通过绑定Application的onStart()方法进行请求处理。
public synchronized void onStart() {
//开始请求
resumeRequests();
targetTracker.onStart();
}
总结如下图所示:
当Glide在子线程中使用时,只需要监听application的onStart方法进行业务请求的处理,application销毁时,整个应用程序都会被销毁,Glide也会跟随着应用销毁而进行资源释放。所以在子线程中使用,由于传入的context是applicationContext,Glide的生命周期也会和整个应用程序一样。
以上就是字节面试后总结的几个要点,还不会的同学赶紧学起来吧,感谢您的阅读,创造不易,如果您觉得本篇文章对您有帮助,请点击关注小编,您的支持就是小编创作的最大动力!
页面更新:2024-05-16
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号