com.facebook.imagepipeline.core/ImagePipeline.java
[1]取圖片從BitmapCache
>public DataSource<CloseableReference<CloseableImage>> fetchImageFromBitmapCache( ImageRequest imageRequest, Object callerContext)
>> submitFetchRequest()
>>>CloseableProducerToDataSourceAdapter.create()生產(chǎn)者到數(shù)據(jù)源的一個(gè)適配器
該適配器目錄com.facebook.imagepipeline.datasource/CloseableProducerToDataSourceAdapter.java
@看看定義
CloseableProducerToDataSourceAdapter<T> extends AbstractProducerToDataSourceAdapter<CloseableReference<T>>
@跟蹤create方法
create()---> super(producer, settableProducerContext, listener)父類的構(gòu)造方法
>>producer.produceResults(createConsumer(), settableProducerContext)
執(zhí)行父類構(gòu)造方法瞒瘸,父類開(kāi)始 告訴 生成者 開(kāi)始生產(chǎn)作業(yè)了produceResults();
@那么這個(gè)producer生產(chǎn)者是誰(shuí)呢?
:::::: producerSequence這玩意
> Producer<CloseableReference<CloseableImage>> producerSequence =
mProducerSequenceFactory.getDecodedImageProducerSequence(imageRequest);
^
@mProducerSequenceFactory工廠產(chǎn)生生產(chǎn)者
^
public Producer<CloseableReference<CloseableImage>> getDecodedImageProducerSequence(ImageRequest imageRequest) {
Producer<CloseableReference<CloseableImage>> pipelineSequence =
getBasicDecodedImageSequence(imageRequest);
if (imageRequest.getPostprocessor() != null) {
return getPostprocessorSequence(pipelineSequence);
} else {
return pipelineSequence;
}
}
@看看pipelineSequence怎么得來(lái):
private Producer<CloseableReference<CloseableImage>> getBasicDecodedImageSequence(ImageRequest imageRequest) {
Preconditions.checkNotNull(imageRequest);//判空
Uri uri = imageRequest.getSourceUri();//圖片地址
Preconditions.checkNotNull(uri, "Uri is null.");//判空
if (UriUtil.isNetworkUri(uri)) {//網(wǎng)絡(luò)地址
return getNetworkFetchSequence();
} else if (UriUtil.isLocalFileUri(uri)) {//本地文件地址
if (MediaUtils.isVideo(MediaUtils.extractMime(uri.getPath()))) {
return getLocalVideoFileFetchSequence();
} else {
return getLocalImageFileFetchSequence();
}
} else if (UriUtil.isLocalContentUri(uri)) {//content地址 如 content://sms/inbox
return getLocalContentUriFetchSequence();
} else if (UriUtil.isLocalAssetUri(uri)) {//本地Asset地址
return getLocalAssetFetchSequence();
} else if (UriUtil.isLocalResourceUri(uri)) {//本地Resource地址
return getLocalResourceFetchSequence();
} else if (UriUtil.isDataUri(uri)) {
return getDataFetchSequence();
} else {
String uriString = uri.toString();
if (uriString.length() > 30) {
uriString = uriString.substring(0, 30) + "...";
}
throw new RuntimeException("Unsupported uri scheme! Uri is: " + uriString);
}
}
根據(jù)uri類型 來(lái)返回 不同的 Producer生產(chǎn)者.
@繼續(xù)跟代碼
1、如果是網(wǎng)絡(luò)地址 getNetworkFetchSequence();
> mNetworkFetchSequence = newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence());
>>
private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToDecodeSequence(Producer<EncodedImage> inputProducer) {
DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(inputProducer);
return newBitmapCacheGetToBitmapCacheSequence(decodeProducer);
}
com.facebook.imagepipeline.core/ProducerFactory.java
先是 調(diào)用工廠類 ProducerFactory.newDecodeProducer得到一個(gè)DecodeProducer解碼生產(chǎn)者
newBitmapCacheGetToBitmapCacheSequence(inputProducer)做了啥?
:ProducerFactory生了BitmapMemoryCacheProducer久免,進(jìn)化成BitmapMemoryCacheKeyMultiplexProducer颁井,再次進(jìn)化ThreadHandoffProducer【這貨后面有用到】
然并卵
return mProducerFactory.newBitmapMemoryCacheGetProducer(threadHandoffProducer);
> ||
public BitmapMemoryCacheGetProducer newBitmapMemoryCacheGetProducer(
Producer<CloseableReference<CloseableImage>> inputProducer) {
return new BitmapMemoryCacheGetProducer(mBitmapMemoryCache, mCacheKeyFactory, inputProducer);
}
最后超級(jí)進(jìn)化成 @BitmapMemoryCacheGetProducer
@2大工廠 @ProducerSequenceFactory 和 @ProducerFactory 前面又字面意思可以理解 一系列工廠翅敌,肯定是總廠音诈,下面很多分廠;
回到主線 producer.produceResults(createConsumer(), settableProducerContext); 找到了 生產(chǎn)者就要開(kāi)始生產(chǎn)了P逭拧4鹩妗!
主角是 BitmapMemoryCacheGetProducer 官方注釋是 只讀的生產(chǎn)者,暫時(shí)有點(diǎn)懵逼
主角父親是BitmapMemoryCacheProducer這貨
@Override
public void produceResults(final Consumer<CloseableReference<CloseableImage>> consumer, final ProducerContext producerContext) {
final ProducerListener listener = producerContext.getListener();
final String requestId = producerContext.getId();
listener.onProducerStart(requestId, getProducerName());//告訴listener開(kāi)始生產(chǎn)
final ImageRequest imageRequest = producerContext.getImageRequest();
final CacheKey cacheKey = mCacheKeyFactory.getBitmapCacheKey(imageRequest);//先取緩存鑰匙
CloseableReference<CloseableImage> cachedReference = mMemoryCache.get(cacheKey);//取圖片
if (cachedReference != null) {//緩存存在
boolean isFinal = cachedReference.get().getQualityInfo().isOfFullQuality();
if (isFinal) {
listener.onProducerFinishWithSuccess(
requestId,
getProducerName(),
listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "true") : null);
consumer.onProgressUpdate(1f);//進(jìn)度報(bào)告 完美
}
consumer.onNewResult(cachedReference, isFinal);//消費(fèi)者 得到 產(chǎn)品
cachedReference.close();
if (isFinal) {
return;
}
}
if (producerContext.getLowestPermittedRequestLevel().getValue() >=
ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE.getValue()) {//最低請(qǐng)求等級(jí)判斷 ,BITMAP_MEMORY_CACHE是最高等級(jí)
listener.onProducerFinishWithSuccess(
requestId,
getProducerName(),
listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
consumer.onNewResult(null, true);
return;
}
//包裝消費(fèi)者
Consumer<CloseableReference<CloseableImage>> wrappedConsumer = wrapConsumer(consumer, cacheKey);
listener.onProducerFinishWithSuccess(requestId,
getProducerName(),
listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
mInputProducer.produceResults(wrappedConsumer, producerContext);//再次生產(chǎn)
}
@RequestLevel.java 是com.facebook.imagepipeline.request.ImageRequest的內(nèi)部類
/* Fetch (from the network or local storage) */
FULL_FETCH(1),
/* Disk caching */
DISK_CACHE(2),
/* Encoded memory caching */
ENCODED_MEMORY_CACHE(3),
/* Bitmap caching */
BITMAP_MEMORY_CACHE(4);
mInputProducer是誰(shuí)呢? 另一個(gè)生產(chǎn)者閃亮登場(chǎng)了 ThreadHandoffProducer 這貨
這貨是 怎么 產(chǎn)生的?
ThreadHandoffProducer<CloseableReference<CloseableImage>> threadHandoffProducer =
mProducerFactory.newBackgroundThreadHandoffProducer(bitmapKeyMultiplexProducer, mThreadHandoffProducerQueue);
還是離不開(kāi)ProducerFactory工廠類
參數(shù)2:mThreadHandoffProducerQueue 侥涵,它里面 有一個(gè)Executor 線程執(zhí)行器 和 ArrayList<Runnable>容器沼撕;
其實(shí) 就是 一個(gè) 線程池吧。
//ThreadHandoffProducer開(kāi)始生產(chǎn)
@Override
public void produceResults(final Consumer<T> consumer, final ProducerContext context) {
final ProducerListener producerListener = context.getListener();
final String requestId = context.getId();
final StatefulProducerRunnable<T> statefulRunnable = new StatefulProducerRunnable<T>(
consumer, producerListener, PRODUCER_NAME, requestId) {
@Override
protected void onSuccess(T ignored) {
producerListener.onProducerFinishWithSuccess(requestId, PRODUCER_NAME, null);
mInputProducer.produceResults(consumer, context);//關(guān)鍵是 這句代碼
}
@Override
protected void disposeResult(T ignored) {
}
@Override
protected T getResult() throws Exception {
return null;
}
};
context.addCallbacks(new BaseProducerContextCallbacks() {
@Override
public void onCancellationRequested() {
statefulRunnable.cancel();
mThreadHandoffProducerQueue.remove(statefulRunnable);
}
});
mThreadHandoffProducerQueue.addToQueueOrExecute(statefulRunnable); //丟到線程池 執(zhí)行
}
在 onSuccess()回調(diào)方法里 ThreadHandoffProducer的mInputProducer開(kāi)始 登場(chǎng)芜飘,
此mInputProducer引用的對(duì)象是 BitmapMemoryCacheKeyMultiplexProducer bitmapKeyMultiplexProducer =
mProducerFactory.newBitmapMemoryCacheKeyMultiplexProducer(bitmapMemoryCacheProducer);
順藤摸瓜 跟到BitmapMemoryCacheKeyMultiplexProducer的父類 MultiplexProducer
>produceResults()
>>startInputProducerIfHasAttachedConsumers()
>>>mInputProducer.produceResults(forwardingConsumer, multiplexProducerContext);
最后 又把任務(wù)交給 另一個(gè)生產(chǎn)者mInputProducer
BitmapMemoryCacheProducer bitmapMemoryCacheProducer =
mProducerFactory.newBitmapMemoryCacheProducer(inputProducer);
看看 BitmapMemoryCacheProducer 的
@Override
public void produceResults(final Consumer<CloseableReference<CloseableImage>> consumer,
final ProducerContext producerContext) {
......
Consumer<CloseableReference<CloseableImage>> wrappedConsumer = wrapConsumer(consumer, cacheKey);
listener.onProducerFinishWithSuccess(
requestId,
getProducerName(),
listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
mInputProducer.produceResults(wrappedConsumer, producerContext);
}
哭笑不得 又交給 另一個(gè)生產(chǎn)者mInputProducer
只能往回看代碼了 :
DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(inputProducer);
解碼生產(chǎn)者
@Override
public void produceResults(final Consumer<CloseableReference<CloseableImage>> consumer,
final ProducerContext producerContext) {
final ImageRequest imageRequest = producerContext.getImageRequest();
ProgressiveDecoder progressiveDecoder;
if (!UriUtil.isNetworkUri(imageRequest.getSourceUri())) {//不是網(wǎng)絡(luò)地址
progressiveDecoder = new LocalImagesProgressiveDecoder(consumer, producerContext);
} else { //是網(wǎng)絡(luò)圖片地址
ProgressiveJpegParser jpegParser = new ProgressiveJpegParser(mByteArrayPool);
progressiveDecoder = new NetworkImagesProgressiveDecoder(consumer,
producerContext,
jpegParser,
mProgressiveJpegConfig);
}
mInputProducer.produceResults(progressiveDecoder, producerContext);
}
繼續(xù)跟 這個(gè) mInputProducer,找源頭吧
private synchronized Producer<CloseableReference<CloseableImage>> getNetworkFetchSequence() {
if (mNetworkFetchSequence == null) {
mNetworkFetchSequence = newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence());
}
return mNetworkFetchSequence;
}
到這里 getCommonNetworkFetchToEncodedMemorySequence()返回生產(chǎn)者
/**
* multiplex -> encoded cache -> disk cache -> (webp transcode) -> network fetch.
*/
private synchronized Producer<EncodedImage> getCommonNetworkFetchToEncodedMemorySequence() {
if (mCommonNetworkFetchToEncodedMemorySequence == null) {
Producer<EncodedImage> inputProducer = newEncodedCacheMultiplexToTranscodeSequence(
mProducerFactory.newNetworkFetchProducer(mNetworkFetcher)); //這里是生存者 源頭
mCommonNetworkFetchToEncodedMemorySequence =
ProducerFactory.newAddImageTransformMetaDataProducer(inputProducer);
if (mResizeAndRotateEnabledForNetwork && !mDownsampleEnabled) { //需要調(diào)整大小 和 旋轉(zhuǎn)
mCommonNetworkFetchToEncodedMemorySequence = mProducerFactory.newResizeAndRotateProducer(
mCommonNetworkFetchToEncodedMemorySequence);
}
}
return mCommonNetworkFetchToEncodedMemorySequence;
}
直接看源頭NetworkFetchProducer 網(wǎng)絡(luò)獲取生產(chǎn)者(從網(wǎng)絡(luò)獲取圖片唄)
@Override
public void produceResults(Consumer<EncodedImage> consumer, ProducerContext context) {
context.getListener()
.onProducerStart(context.getId(), PRODUCER_NAME);
final FetchState fetchState = mNetworkFetcher.createFetchState(consumer, context);
mNetworkFetcher.fetch(fetchState, new NetworkFetcher.Callback() {
@Override
public void onResponse(InputStream response, int responseLength) throws IOException {
NetworkFetchProducer.this.onResponse(fetchState, response, responseLength);
}
@Override
public void onFailure(Throwable throwable) {
NetworkFetchProducer.this.onFailure(fetchState, throwable);
}
@Override
public void onCancellation() {
NetworkFetchProducer.this.onCancellation(fetchState);
}
});
}
mNetworkFetcher是 由 ImagePipelineConfig 初始化的 時(shí)候配置的
mNetworkFetcher = builder.mNetworkFetcher == null ?
new HttpUrlConnectionNetworkFetcher() : builder.mNetworkFetcher;
默認(rèn)配置下ImagePipelineConfig.Builder類的 mNetworkFetcher為 null务豺;
mNetworkFetcher 指向的 就是 HttpUrlConnectionNetworkFetcher,F(xiàn)resco默認(rèn)的網(wǎng)絡(luò)連接用的是HttpUrlConnection;
HttpUrlConnectionNetworkFetcher的 fetch() 方法里
@Override
public void fetch(final FetchState fetchState, final Callback callback) {
final Future<?> future = mExecutorService.submit(new Runnable() {
@Override
public void run() {
fetchSync(fetchState, callback);
}
});//開(kāi)了個(gè)線程執(zhí)行下載圖片操作
......
}
void fetchSync(FetchState fetchState, Callback callback) {
HttpURLConnection connection = null;
try {
connection = downloadFrom(fetchState.getUri(), MAX_REDIRECTS);//終于要下載了
if (connection != null) {
callback.onResponse(connection.getInputStream(), -1);
}
} catch (IOException e) {
callback.onFailure(e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
以上是網(wǎng)絡(luò)加載圖片步驟...