日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Glide核心设计一:皮皮虾,我们走

發(fā)布時間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Glide核心设计一:皮皮虾,我们走 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文鏈接:Glide核心設(shè)計一:皮皮蝦,我們走

引言

皮皮蝦,又名蝦姑,是淡水中的強者。其頭部的兩個錘節(jié),可以輕易破壞貝類的外殼,身體上的步足可以保證快速移動。這些優(yōu)秀的品質(zhì),使它被表情包盯上。

Glide,作為Android最優(yōu)秀的圖片加載框架之一,能和Activity和Fragment的生命周期綁定,是區(qū)別于其它網(wǎng)絡(luò)框架的核心特征,也是本文分析的重點。

我們將此特征和皮皮蝦表情包做一個類比:

皮皮蝦和Glide類比
圖片網(wǎng)絡(luò)請求緊跟Activity、Fragment的生命周期,當(dāng)頁面不可交互時自動停止加載,當(dāng)回到可交互狀態(tài)時,繼續(xù)加載。就像表情包(Activity、Fragment)控制皮皮蝦(圖片請求)一樣。

框架設(shè)計

簡單使用

Glide.with(Context).load(String).into(ImageView)可實現(xiàn)從網(wǎng)絡(luò)中獲取圖片并展示到ImageView當(dāng)中。其中和頁面作生命周期綁定的主要入口是Glide.with(Context)。按照一般的分析邏輯應(yīng)該先分析源碼,才得出結(jié)論,但因一入源碼深似海,不利于整體把握,所以先給出結(jié)論。Glide.with(Context)返回的是一個RequestManager,我們來看RequestManager的類的說明注釋。

A class for managing and starting requests for Glide. Can use activity, fragment and connectivity lifecycle events to intelligently stop, start, and restart requests. Retrieve either by instantiating a new object, or to take advantage built in Activity and Fragment lifecycle handling, use the static Glide.load methods with your Fragment or Activity.

由此可知,該類就是用于將請求Activity或Framgent的生命周期做綁定。

類圖

將和生命周期相關(guān)的類圖如下(省略大部分類的變量和方法):

聲明周期綁定類圖

類的簡單介紹

  • RequestManagerRetriever:該類用于創(chuàng)建RequestManager或在Activity、Fragment中找出已創(chuàng)建的RequestManager,RequestManagerRetriever是一個單例。
  • RequestManagerFragment:繼承Fragment,不可見,僅用于保存RequestManager,還有一個SupportRequestManagerFragment繼承v4包的Fragment,功能類似。
  • LifecycleListener:用于監(jiān)聽Activity、Fragment的生命周期事件。
  • Lifecycle:用于添加LifecycleListener。
  • ActivityFragmentLifecycle:實現(xiàn)Livecycle接口,用于通知Activity、Fragment的生命周期事件。
  • RequestTracker:該類用于跟蹤、取消和重新啟動執(zhí)行中、已完成和失敗的請求。
  • ConnectivityMonitor: 監(jiān)聽網(wǎng)絡(luò)事件的接口,當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生變化時,影響網(wǎng)絡(luò)請求狀態(tài),繼承LifecycleListener。
  • DefaultConnectivityMonitor: ConnectivityMonitor的實現(xiàn)類,實現(xiàn)監(jiān)聽網(wǎng)絡(luò)狀態(tài)的邏輯。
  • RequestManagerConnectivityListener: 實現(xiàn)ConnectivityListener接口,將網(wǎng)絡(luò)事件傳遞給RequestTracker。
  • 類的聯(lián)系

    以上對各類有一個簡單的了解,接下來將重點講清楚各類之間的聯(lián)系。整個生命周期的綁定分為四部分。

  • 調(diào)用Glide.with(Context),根據(jù)傳入的Context類型創(chuàng)建RequestManager。Context可以為Activity、Fragment和Application。
  • 在傳入的參數(shù)Activity、或者Fragment中,添加一個不可見的Fragment,監(jiān)聽不可見Fragment的生命周期并將該事件傳遞給和Fragment一一綁定的RequestManager。
  • RequestManager監(jiān)聽到生命事件后,管理圖片請求做出響應(yīng)。
  • 監(jiān)聽當(dāng)網(wǎng)絡(luò)從無到有時,RequestManager要重新啟動圖片請求。
  • 代碼解讀

    根據(jù)以上內(nèi)容可直接跟代碼可跳過以下內(nèi)容,印象更加深刻。

    第一部分:Glide.with(Context)

    public static RequestManager with(Context context) {RequestManagerRetriever retriever = RequestManagerRetriever.get();return retriever.get(context);} `復(fù)制代碼

    調(diào)用RequestManagerRetriever的get方法如下:

    public RequestManager get(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) { //傳入的是Fragmentreturn get((FragmentActivity) context);} else if (context instanceof Activity) { //傳入的是Acitivityreturn get((Activity) context);} else if (context instanceof ContextWrapper) { //傳入的是Applicationreturn get(((ContextWrapper) context).getBaseContext());}}return getApplicationManager(context);}復(fù)制代碼

    以傳入?yún)?shù)為Activity類型為例,代碼如下:

    public RequestManager get(Activity activity) {if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {return get(activity.getApplicationContext());} else {assertNotDestroyed(activity);android.app.FragmentManager fm = activity.getFragmentManager(); //獲取FragmentManagerreturn fragmentGet(activity, fm); }}復(fù)制代碼

    主要調(diào)用fragmentGet方法,代碼如下:

    RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {RequestManagerFragment current = getRequestManagerFragment(fm); RequestManager requestManager = current.getRequestManager(); //根據(jù)RequestManagerFragment獲取RequestManager,一個RequestManagerFragment包含一個RequestManagerif (requestManager == null) { //若RequestManager為空,則新建一個并且設(shè)置到RequestManagerFragment中requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());current.setRequestManager(requestManager);}return requestManager;}復(fù)制代碼

    getRequestManagerFragment(fm)函數(shù)主要是根據(jù)FragmentManager獲取Fragment,代碼如下:

    RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG); //通過Tag查找if (current == null) { //若為空,從緩存pendingRequestManagerFragments中查找current = pendingRequestManagerFragments.get(fm);if (current == null) { //緩存中也不存在,則新建一個RequestManagerFragment,并且添加到頁面中。current = new RequestManagerFragment();pendingRequestManagerFragments.put(fm, current);fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();}}return current;}復(fù)制代碼

    以上就是根據(jù)傳入的Context類型創(chuàng)建RequestManager的代碼部分。

    第二部分:監(jiān)聽不可見Fragment的生命周期并傳遞給RequestManager

    添加不可見Fragment的目的,就是因為該Fragment和父類的Activity具有同樣的生命周期,無須改動原有Activity的代碼,即可實現(xiàn)生命周期的監(jiān)聽。
    RequestManagerFragment生命周期相關(guān)的代碼如下:

    @Overridepublic void onStart() {super.onStart();lifecycle.onStart(); //執(zhí)行l(wèi)ifecycle的onStart方法}@Overridepublic void onStop() {super.onStop();lifecycle.onStop();//執(zhí)行l(wèi)ifecycle的onStop方法}@Overridepublic void onDestroy() {super.onDestroy();lifecycle.onDestroy();//執(zhí)行l(wèi)ifecycle的onDestroy方法}復(fù)制代碼

    可以看出,Fragment的聲明周期的監(jiān)聽都轉(zhuǎn)移到類型是ActivityFragmentLifecycle的變量lifecycle中的對應(yīng)方法執(zhí)行。查看ActivityFragmentLifecycle的代碼:

    void onStart() {isStarted = true;//循環(huán)set集合lifecycleListeners中所有LifecycleListener,執(zhí)行對應(yīng)的onStartfor (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onStart();}}//省略onStop()和onDestroy()方法,和onStart()方法類似。復(fù)制代碼

    set集合的LifecycleListener是如何添加進(jìn)去的,看ActivityFragmentLifecycle中的代碼:

    @Overridepublic void addListener(LifecycleListener listener) {lifecycleListeners.add(listener);if (isDestroyed) {//如果當(dāng)前頁面已經(jīng)被destroy,則調(diào)用對應(yīng)的onDestroylistener.onDestroy();} else if (isStarted) {//如果當(dāng)前頁面已經(jīng)開啟,則調(diào)用對應(yīng)的onStartlistener.onStart();} else { //其他情況調(diào)用onStop方法listener.onStop();}}復(fù)制代碼

    addListener(LifecycleListener listener)方法是接口Lifecycle的方法。RequestManagerFragment提供一個公有方法:

    ActivityFragmentLifecycle getLifecycle() {return lifecycle;}復(fù)制代碼

    回看第一部分創(chuàng)建RequestManager時:

    requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());復(fù)制代碼

    RequestManagerFragment中的Lifecycle作為RequestManager的構(gòu)造函數(shù)的參數(shù)傳遞給RequestManager。RequestManager構(gòu)造函數(shù)如下:

    RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,RequestTracker requestTracker, ConnectivityMonitorFactory factory) {this.context = context.getApplicationContext();this.lifecycle = lifecycle;this.treeNode = treeNode;this.requestTracker = requestTracker;this.glide = Glide.get(context);this.optionsApplier = new OptionsApplier();//監(jiān)聽網(wǎng)絡(luò)變化的類ConnectivityMonitor connectivityMonitor = factory.build(context,new RequestManagerConnectivityListener(requestTracker));// If we're the application level request manager, we may be created on a background thread. In that case we// cannot risk synchronously pausing or resuming requests, so we hack around the issue by delaying adding// ourselves as a lifecycle listener by posting to the main thread. This should be entirely safe.if (Util.isOnBackgroundThread()) {new Handler(Looper.getMainLooper()).post(new Runnable() {@Overridepublic void run() {//在主線程中將當(dāng)前類實現(xiàn)的LifecycleListener添加到lifecycle中。lifecycle.addListener(RequestManager.this);}});} else {//在主線程中將當(dāng)前類實現(xiàn)的LifecycleListener添加到lifecycle中。lifecycle.addListener(this);}lifecycle.addListener(connectivityMonitor);}復(fù)制代碼

    由此可見,lifecycle添加的就是RequestManager實現(xiàn)的LifecycleListener接口。

    第三部分:RequestManager實現(xiàn)LifecycleListener

    接著查看RequestManager實現(xiàn)LifecycleListener的方法:

    @Overridepublic void onStart() {// onStart might not be called because this object may be created after the fragment/activity's onStart method.resumeRequests();}@Overridepublic void onStop() {pauseRequests();}@Overridepublic void onDestroy() {requestTracker.clearRequests();}復(fù)制代碼

    繼續(xù)進(jìn)入resumeRequests()、pauseRequests()和requestTracker.clearRequests()方法可知,都是調(diào)用RequestTracker相應(yīng)的方法,RequestTracker類包含一個集合的Request,該集合包含一個Activity獲取一個
    Fragment的所以圖片請求,將根據(jù)RequestManagerFragment的生命周期,統(tǒng)一管理圖片請求。

    第四部分:監(jiān)聽網(wǎng)絡(luò)狀態(tài)并作出相應(yīng)

    RequestManager的構(gòu)造函數(shù)有如下方法:

    //省略部分代碼...//監(jiān)聽網(wǎng)絡(luò)變化的類ConnectivityMonitor connectivityMonitor = factory.build(context,new RequestManagerConnectivityListener(requestTracker));//省略部分代碼...lifecycle.addListener(connectivityMonitor); //省略部分代碼...復(fù)制代碼

    以上代碼可看出,ConnectivityMonitor也實現(xiàn)了LifecycleListener。繼續(xù)跟蹤代碼發(fā)現(xiàn),factory的實例是ConnectivityMonitorFactory,在該工廠中會檢查網(wǎng)絡(luò)權(quán)限,同時創(chuàng)建ConnectivityMonitor的實例DefaultConnectivityMonitor。LifecycleListener接口的實現(xiàn)如下:

    @Overridepublic void onStart() {register(); //register()方法為注冊廣播監(jiān)聽網(wǎng)絡(luò)變化}@Overridepublic void onStop() {unregister(); //解除監(jiān)聽廣播}@Overridepublic void onDestroy() {// Do nothing.}復(fù)制代碼

    廣播接收器代碼如下:

    private final BroadcastReceiver connectivityReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {boolean wasConnected = isConnected;isConnected = isConnected(context);if (wasConnected != isConnected) { //當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生變化時,才調(diào)用listener.onConnectivityChanged()方法listener.onConnectivityChanged(isConnected);}}};復(fù)制代碼

    ConnectivityListener 的實例的類型是RequestManager的內(nèi)部類,代碼如下:

    private static class RequestManagerConnectivityListener implements ConnectivityMonitor.ConnectivityListener {private final RequestTracker requestTracker;public RequestManagerConnectivityListener(RequestTracker requestTracker) {this.requestTracker = requestTracker;}@Overridepublic void onConnectivityChanged(boolean isConnected) {if (isConnected) { //如果當(dāng)前狀態(tài)是鏈接狀態(tài)requestTracker.restartRequests(); //重新開啟圖片請求}}}復(fù)制代碼

    小結(jié)

    以上就是Glide實現(xiàn)圖片加載和Activity、Fragment生命周期綁定的全部分析。會發(fā)現(xiàn)使用了觀察者模式和工廠模式進(jìn)行解耦,其中創(chuàng)建一個不可見的Fragment設(shè)置到需要被監(jiān)控生命周期的Activity、Fragment中,最為精彩。接下來將分析Glide核心設(shè)計二:圖片緩存。敬請期待。

    轉(zhuǎn)載于:https://juejin.im/post/58abfbe95c497d005f732e0d

    總結(jié)

    以上是生活随笔為你收集整理的Glide核心设计一:皮皮虾,我们走的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。