decodehelper類中,呼叫的方法,涉及到的東西比較多,最主要的是包括管理元件註冊以擴充套件或替換glide的預設載入,解碼和編碼邏輯的registry類。在glide類的構造方法中,如下:
glide(
@nonnull context context,
@nonnull engine engine,
@nonnull memorycache memorycache,
@nonnull arraypool arraypool,
@nonnull requestmanagerretriever requestmanagerretriever,
@nonnull connectivitymonito***ctory connectivitymonito***ctory,
int loglevel,
@nonnull requestoptions defaultrequestoptions,
@nonnull map, transitionoptions<?, ?>> defaulttransitionoptions)
暫且先有點這個印象,註冊的過程不是我們要重點關注的,registry不過只是一種構造modelloader的實現而已,下面我們先分析decodehelper的getloaddata的實現。
list> getloaddata() }}
return loaddata;
}
這裡的model是乙個object物件,對於我們的簡單url請求來說,它就是乙個string類物件。通過**追蹤,getmodelloaders方法,會返回乙個modelloader的list,它的實現如下:
public list> getmodelloaders(@nonnull model model)
return result;
}
繼續跟進modelloaderregistry的getmodelloaders,
public synchronized list> getmodelloaders(@nonnull a model)
}return filteredloaders;
}
先是呼叫取model的class型別,然後通過getmodelloadersforclass去獲取前面註冊進去的loaders資訊。獲取到之後,通過modelloader的handles方法進行一次過濾。最終返回,我們繼續分析getmodelloadersforclass。
private list> getmodelloadersforclass(@nonnull classmodelclass)
return loaders;
}
可以看到,它是由multimodelloade***ctory.build方法返回值決定的。下面繼續分析這個方法。
synchronized list> build(@nonnull classmodelclass)
if (entry.handles(modelclass))
}return loaders;
} catch (throwable t)
}
entry我們上面已經有所介紹,和string有關的目前有四個,重點就是entry.handles方法的返回值,決定其是否能加入到loaders中,而在這個方法中,實現就是看是否和modelclass能夠匹配,所以此時和string.class能匹配的就是上面已經列出的。
接下來會呼叫build方法傳入entry獲取乙個modelloader物件,build實現如下:
private modelloaderbuild(@nonnull entry<?, ?> entry)
這裡就是呼叫entry對應的factory物件去構建modelloader。這裡四個工廠分別是dataurlloader.streamfactory、stringloader.streamfactory、stringloader.filedescripto***ctory與stringloader.assetfiledescripto***ctory。分別構造了dataurlloader、stringloader、stringloader、stringloader四個loader物件。
對於乙個url,這裡我們的是:"",modelloader中有乙個handles方法,表明此型別是否可以被自己處理。
dataurlloader的實現如下:
public boolean handles(@nonnull model model)
其中data_scheme_image為"data:image",顯然此時不能處理我們的url。
stringloader的實現如下:
public boolean handles(@nonnull string model)
顯然此時,是可以處理這個url物件的。 三個factory的build方法的實現如下:
public static class streamfactory implements modelloade***ctory
} /**
* factory for loading s from strings.
*/public static class filedescripto***ctory
implements modelloade***ctory
} /**
* loads s from strings.
*/public static final class assetfiledescripto***ctory
implements modelloade***ctory
}
這塊相對有點複雜,在stringloader中有乙個成員變數uriloader,它也是由entry傳入的multimodelloade***ctory的build方法繼續建立的。這裡我們可以看到有乙個遞迴的過程,其實也很好理解,雖然三個都是stringloader,但內部的成員變數uriloader不一樣。分別是三對:
uri.class, inputstream.class
uri.class, parcelfiledescriptor.class
uri.class, assetfiledescriptor.class
這裡其實和之前的邏輯類似,也是從glide中查表,繼續看關於這三對的註冊情況。仍然是在glide構造方法中註冊的。
new uriloader.assetfiledescripto***ctory(contentresolver))
因此,上面三個stringloader中,成員變數uriloader分別為:
multimodelloader:[asseturiloader、uriloader]
uriloadermodelloader最重要的功能就是通過buildloaddata建立相應的loaddata物件。
multimodelloader實現如下:
public loaddatabuildloaddata(@nonnull model model, int width, int height,
@nonnull options options) }}
return !fetchers.isempty() && sourcekey != null
? new loaddata<>(sourcekey, new multifetcher<>(fetchers, exceptionlistpool)) : null;
}
對於我們的三種情況來講,考慮到handles的過濾,model是"",因此最終建立的loaddata的fetchers資訊如下:
loaddata: [,]
loaddata:
loaddata:至此返回的三個stringloader以及最終建立的loaddata也就理清楚了。下面回到decodehelper的getloaddata中:
list> getloaddata() }}
return loaddata;
}
這裡就是呼叫前面建立的三個stringloader,而後呼叫其buildloaddata方法,獲取到相應的loaddata物件,這裡我們可以知道,最終的loaddata這個列表如下:
,]},至此,再看getcachekeys的實現也就非常簡單了。]}
listgetcachekeys()
for (int j = 0; j < data.alternatekeys.size(); j++) }}
}return cachekeys;
}
因此此時的cachekeys中的內容就是:
[glideurl,objectkey]這裡我們分析了decodehelper類中,最複雜的獲取loaddata的方法,沒有在註冊這塊花太大的精力,後面的分析中,我們會看到這個輔助類的使用。
採集相關類
using system using system.data using system.configuration using system.net using system.io using system.text using system.collections.generic using sy...
執行緒相關類(ThreadLocal類)
threadlocal,是tread local varcable 執行緒區域性變數 的意思。執行緒區域性變數 threadlocal 的功能其實非常簡單,就是為每乙個使用該變數的執行緒都提供乙個變數值的副本 threadlocal是採用雜湊表的方式來為每個執行緒都提供乙個變數的副本 而不會和其它執...
C 類及其相關
類是一種引用型別,在了解了類的一些基礎知識以後,對一些容易忽略的內容進行總結。1 呼叫基類構造器 作為乙個良好的程式設計習慣,派生類的構造器在執行初始化時,最好呼叫一下它的基類的構造器。為派生類定義構造器時,可以使用base關鍵字來指定呼叫乙個基類的構造器。下例 class mammal class...