本文通过在字节面试遇到的问题总结而出,如有不对的地方,请及时批评指正。篇幅较长,请耐心阅读。如果您想了解其他框架源码,欢迎评论区留言! 篇幅较长,请耐心阅读〔玫瑰〕 简介 Glide是一个优秀的图片加载框架,支持多种数据源,功能强大,性能高。如图所示: 使用步骤 1。在build。gradle中添加glide引用implementationcom。github。bumptech。glide:glide:4。12。0 2。使用glide加载图片Glide。with(this)。load(BASEPICURL)。into(imguser)源码分析设计模式1。单例模式 Glide使用了单例设计模式,通过双重校验锁机制不仅保证了Glide对象的全局单例,而且解决了多线程环境下的并发安全问题。2。工厂设计模式 Glide内部的创建RequestManager对象时使用了工厂设计模式,通过定义RequestManagerFactory抽象接口,让其子类创建RequestManager对象,隐藏其内部创建逻辑。3。建造者设计模式 Glide使用了静态类GlideBuilder构建Glide对象,将Glide的各种属性封装到GlideBuilder中,根据不同的属性设置构建不同功能的Glide对象。简化Glide的构建过程。生命周期绑定主线程中使用 1。Glide使用With方法传入所需要的上下文,主线程中一般传context,fragment,activity来实现对生命周期的绑定。publicstaticRequestManagerwith(NonNullContextcontext)publicstaticRequestManagerwith(NonNullActivityactivity)publicstaticRequestManagerwith(NonNullFragmentfragment)publicstaticRequestManagerwith(NonNullFragmentActivityactivity) 2。下面以activity为例,参数传入activity。publicstaticRequestManagerwith(NonNullActivityactivity){returngetRetriever(activity)。get(activity);} 3。通过调用RequestManagerRetriever的get方法,传入activity参数返回RequestManager对象。RequestManager主要负责管理Glide的请求和启动。NonNullpublicRequestManagerget(NonNullActivityactivity){判断是否是后台线程if(Util。isOnBackgroundThread()){returnget(activity。getApplicationContext());}elseif(activityinstanceofFragmentActivity){returnget((FragmentActivity)activity);}else{判断当前activity没有被销毁,否则抛出异常assertNotDestroyed(activity);frameWaiter。registerSelf(activity);获取activity中的FragmentManagerandroid。app。FragmentManagerfmactivity。getFragmentManager();通过fragmentGet方法,创建并返回RequestManagerreturnfragmentGet(activity,fm,parentHintnull,isActivityVisible(activity));}} RequestManagerRetriever的get方法中根据传入的参数不同,使用Util。isOnBackgroundThread判断子线程和主线程分别进行不同的处理。主线程中最终都是调用fragmentGet方法。注意,由于这里的参数是activity,获取的是fragmentManager,如果传入的是fragment,则获取的childFragmentManager。 4。fragmentGet方法主要是通过RequestManagerFragment来获取RequestManager,如果没有获取到,则通过工厂模式进行创建。同时传入fragment的getGlideLifecycle。这个lifecycle是重点,需要注意。privateRequestManagerfragmentGet(NonNullContextcontext,NonNullandroid。app。FragmentManagerfm,Nullableandroid。app。FragmentparentHint,booleanisParentVisible){通过fragmentManager获取RequestManagerFragmentRequestManagerFragmentcurrentgetRequestManagerFragment(fm,parentHint);获取RequestManagerFragment中的requestManagerRequestManagerrequestManagercurrent。getRequestManager();判断requestManagerif(requestManagernull){如果requestManager为空,则通过工厂设计模式创建出requestManagerGlideglideGlide。get(context);requestManagerfactory。build(glide,current。getGlideLifecycle(),current。getRequestManagerTreeNode(),context);如果activity显示出来,则执行requestManager的onStart方法if(isParentVisible){requestManager。onStart();}current。setRequestManager(requestManager);}returnrequestManager;} 5。创建RequestManagerFragment,这里创建一个空白页面的RequestManagerFragment并且绑定到当前activity中。NonNullprivateRequestManagerFragmentgetRequestManagerFragment(NonNullfinalandroid。app。FragmentManagerfm,Nullableandroid。app。FragmentparentHint){通过tag获取fragmentManager中保存的fragmentRequestManagerFragmentcurrent(RequestManagerFragment)fm。findFragmentByTag(FRAGMENTTAG);if(currentnull){如果获取不到,则进一步通过pendingRequestManagerFragmentsMap中获取currentpendingRequestManagerFragments。get(fm);if(currentnull){如果还是获取不到,则进行创建currentnewRequestManagerFragment();current。setParentFragmentHint(parentHint);同时保存到map中pendingRequestManagerFragments。put(fm,current);然后添加到当前activity中fm。beginTransaction()。add(current,FRAGMENTTAG)。commitAllowingStateLoss();将这个添加动作通过handler发送给系统处理handler。obtainMessage(IDREMOVEFRAGMENTMANAGER,fm)。sendToTarget();}}returncurrent;} 6。RequestManagerFragment的构造函数创建了ActivityFragmentLifecycle用来监听RequestManagerFragment的生命周期onStart(),onStop(),onDestroy()。publicSupportRequestManagerFragment(){this(newActivityFragmentLifecycle());}publicSupportRequestManagerFragment(NonNullActivityFragmentLifecyclelifecycle){this。lifecyclelifecycle;}OverridepublicvoidonStart(){super。onStart();lifecycle。onStart();}OverridepublicvoidonStop(){super。onStop();lifecycle。onStop();}OverridepublicvoidonDestroy(){super。onDestroy();lifecycle。onDestroy();} 最后在fragmentGet方法中将ActivityFragmentLifecycle通过工厂设计模式传给RequestManager并返回。 7。ActivityFragmentLifecycle继承于Lifecycle接口。OverridepublicvoidaddListener(NonNullLifecycleListenerlistener){所有的监听者都添加监听lifecycleListeners。add(listener);根据不同的生命周期进行处理if(isDestroyed){listener。onDestroy();}elseif(isStarted){listener。onStart();}else{listener。onStop();}}OverridepublicvoidremoveListener(NonNullLifecycleListenerlistener){移除所有监听lifecycleListeners。remove(listener);}voidonStart(){只添加一次监听isStartedtrue;同步所有生命周期for(LifecycleListenerlifecycleListener:Util。getSnapshot(lifecycleListeners)){lifecycleListener。onStart();}}voidonStop(){isStartedfalse;同步所有生命周期for(LifecycleListenerlifecycleListener:Util。getSnapshot(lifecycleListeners)){lifecycleListener。onStop();}}voidonDestroy(){isDestroyedtrue;同步所有生命周期for(LifecycleListenerlifecycleListener:Util。getSnapshot(lifecycleListeners)){lifecycleListener。onDestroy();}} 8。RequestManager拿到这个lifecycle,进行绑定监听RequestManagerFragment生命周期。RequestManager(Glideglide,Lifecyclelifecycle,RequestManagerTreeNodetreeNode,RequestTrackerrequestTracker,ConnectivityMonitorFactoryfactory,Contextcontext){this。glideglide;this。lifecyclelifecycle;this。treeNodetreeNode;this。requestTrackerrequestTracker;this。contextcontext;。。)。。。。。。。。。。。。。。。。。。。。。。。。。。。判断是否是后台线程if(Util。isOnBackgroundThread()){Util。postOnUiThread(addSelfToLifecycle);}else{添加lifecycle监听lifecycle。addListener(this);}lifecycle。addListener(connectivityMonitor);。。。。。。。。。。。。。。} 9。通过生命周期的绑定处理对应的业务逻辑和资源释放等功能。publicsynchronizedvoidonStart(){开始请求resumeRequests();targetTracker。onStart();}OverridepublicsynchronizedvoidonStop(){开始停止pauseRequests();targetTracker。onStop();}OverridepublicsynchronizedvoidonDestroy(){targetTracker。onDestroy();释放资源targetTracker。clear();requestTracker。clearRequests();lifecycle。removeListener(this);lifecycle。removeListener(connectivityMonitor);Util。removeCallbacksOnUiThread(addSelfToLifecycle);glide。unregisterRequestManager(this);} 总结如下图所示: Glide在主线程中使用时,通过创建一个空白的fragment添加到当前ActivityFragment中,用来监听当前页面的生命周期变化,进行图片的显示或资源的释放。子线程中使用 1。Glide在子线程中使用只能传入applicationContext。publicstaticRequestManagerwith(NonNullContextcontext) 2。通过调用RequestManagerRetriever的get方法,传入activity参数返回RequestManager对象。RequestManager主要负责管理Glide的请求和启动。publicRequestManagerget(NonNullContextcontext){if(contextnull){thrownewIllegalArgumentException(YoucannotstartaloadonanullContext);}elseif(Util。isOnMainThread()!(contextinstanceofApplication)){if(contextinstanceofFragmentActivity){returnget((FragmentActivity)context);}elseif(contextinstanceofActivity){returnget((Activity)context);}elseif(contextinstanceofContextWrapper((ContextWrapper)context)。getBaseContext()。getApplicationContext()!null){returnget(((ContextWrapper)context)。getBaseContext());}}子线程返回applicationManagerreturngetApplicationManager(context);} 3。在getApplicationManager方法中通过双重校验锁的单例方式返回applicationManager,applicationManager的创建使用了工厂设计模式,隐藏了applicationManager的内部创建细节。NonNullprivateRequestManagergetApplicationManager(NonNullContextcontext){if(applicationManagernull){synchronized(this){if(applicationManagernull){GlideglideGlide。get(context。getApplicationContext());applicationManagerfactory。build(glide,newApplicationLifecycle(),newEmptyRequestManagerTreeNode(),context。getApplicationContext());}}}returnapplicationManager;} 4。getApplicationManager创建applicationManager时传入了ApplicationLifecycle作为生命周期监听。RequestManager(Glideglide,Lifecyclelifecycle,RequestManagerTreeNodetreeNode,RequestTrackerrequestTracker,ConnectivityMonitorFactoryfactory,Contextcontext){this。glideglide;this。lifecyclelifecycle;this。treeNodetreeNode;this。requestTrackerrequestTracker;this。contextcontext;。。。。。。。。。。。。。如果是子线程,通过使用Handler切换到主线程if(Util。isOnBackgroundThread()){Util。postOnUiThread(addSelfToLifecycle);}else{lifecycle。addListener(this);}。。。。。。。。。。。。。。。。} 5。RequestManager拿到这个lifecycle,使用Handler切换到主线程进行绑定监听Application生命周期。privatefinalRunnableaddSelfToLifecyclenewRunnable(){Overridepublicvoidrun(){lifecycle。addListener(RequestManager。this);}}; 6。通过绑定Application的onStart()方法进行请求处理。publicsynchronizedvoidonStart(){开始请求resumeRequests();targetTracker。onStart();} 总结如下图所示: 当Glide在子线程中使用时,只需要监听application的onStart方法进行业务请求的处理,application销毁时,整个应用程序都会被销毁,Glide也会跟随着应用销毁而进行资源释放。所以在子线程中使用,由于传入的context是applicationContext,Glide的生命周期也会和整个应用程序一样。 以上就是字节面试后总结的几个要点,还不会的同学赶紧学起来吧,感谢您的阅读,创造不易,如果您觉得本篇文章对您有帮助,请点击关注小编,您的支持就是小编创作的最大动力!