最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

從源碼分析Android的Glide庫的圖片加載流程及特點

 更新時間:2016年04月27日 15:08:35   作者:junjianzhang  
這篇文章主要介紹了從源碼分析Android的Glide庫的圖片加載流程及特點,Glide庫是Android下一款人氣很高的多媒體資源管理庫,特別是在處理gif加載方面受到眾多開發(fā)者青睞,需要的朋友可以參考下

0.基礎知識
Glide中有一部分單詞,我不知道用什么中文可以確切的表達出含義,用英文單詞可能在行文中更加合適,還有一些詞在Glide中有特別的含義,我理解的可能也不深入,這里先記錄一下。

(1)View: 一般情況下,指Android中的View及其子類控件(包括自定義的),尤其指ImageView。這些控件可在上面繪制Drawable
(2)Target: Glide中重要的概念,目標。它即可以指封裝了一個View的Target(ViewTarget),也可以不包含View(SimpleTarget)。
(3)Drawable: 指Android中的Drawable類或者它的子類,如BitmapDrawable等。或者Glide中基礎Drawable實現(xiàn)的自定義Drawable(如GifDrawable等)
(4)Request - 加載請求,可以是網(wǎng)絡請求或者其他任何下載圖片的請求,也是Glide中的一個類。
(5)Model:數(shù)據(jù)源的提供者,如Url,文件路徑等,可以從model中獲取InputStream。
(6)Signature:簽名,可以唯一地標識一個對象。
(7)recycle():Glide中Resource類有此方法,表示該資源不被引用,可以放入池中(此時并沒有釋放空間)。Android中Bitmap也有此方法,表示釋放Bitmap占用的內存。

1.主要特點
(1)支持Memory和Disk圖片緩存。
(2)支持gif和webp格式圖片。
(3)根據(jù)Activity/Fragment生命周期自動管理請求。
(4)使用Bitmap Pool可以使Bitmap復用。
(5)對于回收的Bitmap會主動調用recycle,減小系統(tǒng)回收壓力。

2. 總體設計

2016427150437442.png (961×767)

基本概念
RequestManager:請求管理,每一個Activity都會創(chuàng)建一個RequestManager,根據(jù)對應Activity的生命周期管理該Activity上所以的圖片請求。
Engine:加載圖片的引擎,根據(jù)Request創(chuàng)建EngineJob和DecodeJob。
EngineJob:圖片加載。
DecodeJob:圖片處理。
流程圖
這里是大概的總體流程圖, 具體的細節(jié)中流程下面繼續(xù)分析。

2016427150459886.png (962×1222)

3. 核心類介紹

3.1 Gilde
用于保存整個框架中的配置。
重要方法:

public static RequestManager with(FragmentActivity activity) {
 RequestManagerRetriever retriever = RequestManagerRetriever.get();
 return retriever.get(activity);
}

用于創(chuàng)建RequestManager,這里是Glide通過Activity/Fragment生命周期管理Request原理所在,這個類很關鍵、很關鍵、很關鍵,重要的事情我只說三遍。
主要原理是創(chuàng)建一個自定義Fragment,然后通過自定義Fragment生命周期操作RequestManager,從而達到管理Request。

2016427150542660.png (967×930)

3.2 RequestManagerRetriever

RequestManager supportFragmentGet(Context context, FragmentManager fm) {
 SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
 RequestManager requestManager = current.getRequestManager();
 if (requestManager == null) {
 requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
 current.setRequestManager(requestManager);
 }
 return requestManager;
}

這里判斷是否只當前RequestManagerFragment是否存在RequestManager,保證一個Activity對應一個RequestManager, 這樣有利于管理一個Activity上所有的Request。創(chuàng)建RequestManager的時候會將RequestManagerFragment中的回調接口賦值給RequestManager,達到RequestManager監(jiān)聽RequestManagerFragment的生命周期。

3.3 RequestManager
成員變量:
(1)Lifecycle lifecycle,用于監(jiān)聽RequestManagerFragment生命周期。
(2)RequestTracker requestTracker, 用于保存當前RequestManager所有的請求和帶處理的請求。
重要方法:

@Override
//開始暫停的請求
public void onStart() {
 resumeRequests();
}
//停止所有的請求
@Override
public void onStop() {
 pauseRequests();
}
 
//關閉所以的請求
@Override
public void onDestroy() {
 requestTracker.clearRequests();
}
 
//創(chuàng)建RequestBuild
public DrawableTypeRequest<String> load(String string) {
 return (DrawableTypeRequest<String>) fromString().load(string);
}
 
public <Y extends Target<TranscodeType>> Y into(Y target) {
 ...
 Request previous = target.getRequest();
 //停止當前target中的Request。
 if (previous != null) {
 previous.clear(); //這個地方很關鍵,見Request解析
 requestTracker.removeRequest(previous);
 previous.recycle();
 }
 ...
 return target;
}

3.4 DrawableRequestBuilder
用于創(chuàng)建Request。 這里面包括很多方法,主要是配置加載圖片的url、大小、動畫、ImageView對象、自定義圖片處理接口等。

3.5 Request
主要是操作請求,方法都很簡單。

@Override
public void clear() {
 ...
 if (resource != null) {
 //這里會釋放資源
 releaseResource(resource);
 }
 ...
}

這里的基本原理是當有Target使用Resource(Resource見下文)時,Resource中的引用記數(shù)值會加一,當釋放資源Resource中的引用記數(shù)值減一。當沒有Target使用的時候就會釋放資源,放進Lrucache中。

3.6 EngineResource
實現(xiàn)Resource接口,使用裝飾模式,里面包含實際的Resource對象

void release() {
 if (--acquired == 0) {
 listener.onResourceReleased(key, this);
 }
} 
 
void acquire() {
 ++acquired;
} 
 
@Override
public void recycle() {
 isRecycled = true;
 resource.recycle();
}

acquire和release兩個方法是對資源引用計數(shù);recycle釋放資源,一般在Lrucache飽和時會觸發(fā)。

3.7 Engine(重要)
請求引擎,主要做請求的開始的初始化。
3.7.1 load方法
這個方法很長,將分為幾步分析
(1)獲取MemoryCache中緩存 首先創(chuàng)建當前Request的緩存key,通過key值從MemoryCache中獲取緩存,判斷緩存是否存在。

private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
 ....
 EngineResource<?> cached = getEngineResourceFromCache(key);
 if (cached != null) {
 cached.acquire();
 activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
 }
 return cached;
}
 
@SuppressWarnings("unchecked")
private EngineResource<?> getEngineResourceFromCache(Key key) {
 Resource<?> cached = cache.remove(key);
 
 final EngineResource result;
 ...
 return result;
}

(重點)從緩存中獲取的時候使用的cache.remove(key),然后將值保存在activeResources中,然后將Resource的引用計數(shù)加一。
優(yōu)點:
> 正使用的Resource將會在activeResources中,不會出現(xiàn)在cache中,當MemoryCache中緩存飽和的時候或者系統(tǒng)內存不足的時候,清理Bitmap可以直接調用recycle,不用考慮Bitmap正在使用導致異常,加快系統(tǒng)的回收。
(2)獲取activeResources中緩存
activeResources通過弱引用保存recouse ,也是通過key獲取緩存,

private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable)

(3)判斷當前的請求任務是否已經(jīng)存在

EngineJob current = jobs.get(key);
if (current != null) {
 current.addCallback(cb);
 return new LoadStatus(cb, current);
}

如果任務請求已經(jīng)存在,直接將回調事件傳遞給已經(jīng)存在的EngineJob,用于請求成功后觸發(fā)回調。
(4)執(zhí)行請求任務

EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
 transcoder, diskCacheProvider, diskCacheStrategy, priority);
EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
jobs.put(key, engineJob);
engineJob.addCallback(cb);
engineJob.start(runnable);

3.8 EngineRunnable
請求執(zhí)行Runnable,主要功能請求資源、處理資源、緩存資源。

private Resource<?> decodeFromCache() throws Exception {
 Resource<?> result = null;
 try {
 result = decodeJob.decodeResultFromCache();
 } catch (Exception e) {
 if (Log.isLoggable(TAG, Log.DEBUG)) {
  Log.d(TAG, "Exception decoding result from cache: " + e);
 }
 }
 
 if (result == null) {
 result = decodeJob.decodeSourceFromCache();
 }
 return result;
} 
 
private Resource<?> decodeFromSource() throws Exception {
 return decodeJob.decodeFromSource();
}

加載DiskCache和網(wǎng)絡資源。加載DiskCache包括兩個,因為Glide默認是保存處理后的資源(壓縮和裁剪后),緩存方式可以自定義配置。如果客戶端規(guī)范設計,ImageView大小大部分相同可以節(jié)省圖片加載時間和Disk資源。

3.9 DecodeJob
public Resource<Z> decodeResultFromCache() throws Exception  
從緩存中獲取處理后的資源。上面有關Key的內容,Key是一個對象,可以獲取key和orginKey。decodeResultFromCache就是通過key獲取緩存,decodeSourceFromCache()就是通過orginKey獲取緩存。
private Resource<Z> transformEncodeAndTranscode(Resource<T> decoded)
處理和包裝資源;緩存資源。
保存原資源
private Resource<T> cacheAndDecodeSourceData(A data) throws IOException 
保存處理后的資源
private void writeTransformedToCache(Resource<T> transformed)

3.10 Transformation
Resource<T> transform(Resource<T> resource, int outWidth, int outHeight);
處理資源,這里面出現(xiàn)BitmapPool類,達到Bitmap復用。
3.11 ResourceDecoder
用于將文件、IO流轉化為Resource
3.12 BitmapPool
用于存放從LruCache中remove的Bitmap, 用于后面創(chuàng)建Bitmap時候的重復利用。

4.雜談
Glide的架構擴展性高,但是難以理解,各種接口、泛型,需要一定的學習才能熟練運用。
Glide的優(yōu)點:
(1)支持對處理后的資源Disk緩存。
(2)通過BitmapPool對Bitmap復用。
(3)使用activityResources緩存正在使用的resource,對于BitmapPool飽和移除的Bitmap直接調用recycle加速內存回收。

相關文章

最新評論

尖扎县| 甘洛县| 北宁市| 吉水县| 新泰市| 互助| 阿克苏市| 平度市| 乐平市| 慈利县| 聂拉木县| 朔州市| 宁城县| 和龙市| 辛集市| 柏乡县| 丹凤县| 阿荣旗| 黔江区| 英山县| 玉龙| 光山县| 海盐县| 定州市| 资中县| 宁化县| 台中县| 乐业县| 屯留县| 肇源县| 定西市| 沾益县| 浑源县| 平泉县| 张家口市| 庆安县| 壶关县| 新田县| 西安市| 宁南县| 临安市|