Fresco 소스 감상 분석의 백그라운드 획득 절차
클릭하여 링크 열기
Fresco 원본 감상 분석의 그림 표시 절차는 데이터를 얻은 후 ui의 리셋을 어떻게 완성하는지, Fresco 봉인된 컨트롤러를 어떻게 봉인하고drawable를 관리하는지 간단하게 설명합니다. 이 글을 보고 여기를 클릭하십시오.
클릭하여 링크 열기
본고는 주로 마지막 편에서 분석한 것이다. 주로 Fresco가 백그라운드에서 데이터를 얻는 절차를 구체적으로 살펴보는 것이다. Fresco 원본 코드 감상 분석의 기본 절차에서 잘 설명하지 않았고 원본 코드가 비교적 복잡하기 때문에 분석을 제대로 하지 못했을 수도 있다. 교류 학습을 환영한다.
전재는 출처를 밝혀 주십시오.http://blog.csdn.net/u014614038/article/details/51507236
앞의 두 글에서 알 수 있듯이 Fresco가 데이터를 얻는 과정은 서로 다른 Producer로 나뉘어 서로 다른 임무를 수행한다. 그들 사이에는consumer를 통해 데이터를 전달한다. 이것은 직책체인 모델과 유사하고 서로 다른 Producer는 서로 다른 직책을 가진다. 복잡하게 캐시를 찾고 인코딩을 책임지며 네트워크 데이터를 얻는 것을 책임진다.나는 간단하게 그림을 그렸다.
이것은 간단하고 대략적인 그림으로 Fresco가 데이터를 얻는 전체 절차의 사고방식을 요약하고 설명할 수 있다. 사실상 이것보다 훨씬 복잡할 것이다. 예를 들어 그림에서 모든 Producer는 복잡한 직책을 수행하는 작업이다. 어떤 것은 캐시 데이터를 얻는 것이고 어떤 것은 인코딩, 캐시, 인터넷 취득 등이다.처음에 데이터를 요청한 후에 캐시에서 Producer1에게 요청한 데이터를 가져와야 한다. 요청한 데이터를 가져오지 않으면 다음 작업을 하지 않는다. 캐시에서 Producer1을 가져오지 않으면 다음 Producer 처리에 맡긴다. 이런 식으로 미루어 보면 어쩔 수 없이 네트워크 데이터를 얻는다. 이 기간에 일련의 Producer를 포함하여 하나의 직책 체인을 형성한다.데이터를 얻는 모든 과정을 마쳤다.
요청된 데이터의 입구를 살펴보겠습니다.
@Override
protected DataSource<CloseableReference<CloseableImage>> getDataSourceForRequest(
ImageRequest imageRequest,
Object callerContext,
boolean bitmapCacheOnly) {
if (bitmapCacheOnly) {
return mImagePipeline.fetchImageFromBitmapCache(imageRequest, callerContext);
} else {
return mImagePipeline.fetchDecodedImage(imageRequest, callerContext);
}
}
이 슬라이드에서 간략하게 네트워크 데이터를 가져오는 방법은 Fresco 소스 판독의 기본 절차에 나와 있습니다.
/**
* swallow result if prefetch -> bitmap cache get -> wait if scrolling ->
* background thread hand-off -> multiplex -> bitmap cache -> decode -> multiplex ->
* encoded cache -> disk cache -> (webp transcode) -> network fetch.
*/
private synchronized Producer<CloseableReference<CloseableImage>> getNetworkFetchSequence() {
if (mNetworkFetchSequence == null) {
mNetworkFetchSequence =
newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence());
}
return mNetworkFetchSequence;
}
여기에서 반환된 것은 하나의 네트워크에서 획득한 Producer이다. 사실상 여러 개의 Producer의 체인이다. 여기서 반환된 것은 체인 헤드일 뿐이다. 최종적으로 체인 헤드에서 체인으로 가는 것은 이 과정이 중단될 수도 있고 완전히 끝날 수도 있다. 그러나 코드에서 본 그림은 이 체인은 틀림없이 완전한 것이다. new Bitmap Cache Get To Decode Sequence가 반환한 것은 하나의 Producer이다.다음 pruducer는 get Common Network Fetch To Encoded Memory Sequence () 가 되돌아오는 pruducer입니다. 이 두 가지 방법을 구체적으로 살펴보겠습니다.
먼저 앞부분을 보십시오:
/**
* Same as {@code newBitmapCacheGetToBitmapCacheSequence} but with an extra DecodeProducer.
* @param nextProducer next producer in the sequence after decode
* @return bitmap cache get to decode sequence
*/
private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToDecodeSequence(
Producer<CloseableReference<PooledByteBuffer>> nextProducer) {
DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(nextProducer);// ,
return newBitmapCacheGetToBitmapCacheSequence(decodeProducer);
}
/**
* Bitmap cache get -> wait if scrolling -> thread hand off -> multiplex -> bitmap cache
* @param nextProducer next producer in the sequence after bitmap cache
* @return bitmap cache get to bitmap cache sequence
*/
private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToBitmapCacheSequence(
Producer<CloseableReference<CloseableImage>> nextProducer) {
BitmapMemoryCacheProducer bitmapMemoryCacheProducer =
mProducerFactory.newBitmapMemoryCacheProducer(nextProducer);// bitmap , ,
BitmapMemoryCacheKeyMultiplexProducer bitmapKeyMultiplexProducer =
mProducerFactory.newBitmapMemoryCacheKeyMultiplexProducer(bitmapMemoryCacheProducer);// , ,
ThreadHandoffProducer<CloseableReference<CloseableImage>> threadHandoffProducer =
mProducerFactory.newBackgroundThreadHandoffProducer(bitmapKeyMultiplexProducer);// , pruducer
return mProducerFactory.newBitmapMemoryCacheGetProducer(threadHandoffProducer);// bitmap
}
방법이 전송된 매개 변수가 없는 것을 보면 넥스트 프로듀서, 즉 전송된 프로듀서는 다음 직책을 담당하는 프로듀서이다. 바로 현재 프로듀서가 완성된 후에 필요하면 다음 프로듀서 처리에 맡긴다. 예를 들어 캐시 데이터가 없는 것을 발견하면 이미지 데이터 인코딩의 프로듀서 처리에 맡긴다. 이것은 상관하지 않는다.같은 이치로 mProducerFactory가 전송한 매개 변수의 이름은nextproducer라고 하는데 그것이 만든 그 Producer의 다음 Producer가 바로 전송된 것이다. 이렇게 해서 완전한 체인이 형성되었다.
다음 방법 보기:
/**
* multiplex -> encoded cache -> disk cache -> (webp transcode) -> network fetch.
*/
private synchronized Producer<CloseableReference<PooledByteBuffer>>
getCommonNetworkFetchToEncodedMemorySequence() {
if (mCommonNetworkFetchToEncodedMemorySequence == null) {
mCommonNetworkFetchToEncodedMemorySequence =
newEncodedCacheMultiplexToTranscodeSequence(mNetworkFetchProducer, /* isLocal */false);
if (mResizeAndRotateEnabledForNetwork) {
mCommonNetworkFetchToEncodedMemorySequence =
newResizeAndRotateImagesSequence(mCommonNetworkFetchToEncodedMemorySequence);
}
}
return mCommonNetworkFetchToEncodedMemorySequence;
}
사실 이 mNetwork Fetch Producer야말로 마지막으로 네트워크 요청을 해서 데이터를 얻는 제품입니다. 이렇게 표시합니다.
/**
* encoded cache multiplex -> encoded cache -> (disk cache) -> (webp transcode)
* @param nextProducer next producer in the sequence
* @param isLocal whether the image source is local or not
* @return encoded cache multiplex to webp transcode sequence
*/
private Producer<CloseableReference<PooledByteBuffer>>
newEncodedCacheMultiplexToTranscodeSequence(
Producer<CloseableReference<PooledByteBuffer>> nextProducer,
boolean isLocal) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
nextProducer = mProducerFactory.newWebpTranscodeProducer(nextProducer);//
}
if (!isLocal) {
nextProducer = mProducerFactory.newDiskCacheProducer(nextProducer);//
}
EncodedMemoryCacheProducer encodedMemoryCacheProducer =
mProducerFactory.newEncodedMemoryCacheProducer(nextProducer);// ,
return mProducerFactory.newEncodedCacheKeyMultiplexProducer(encodedMemoryCacheProducer);// ,
}
위의 두 가지 방법에 따라 나는 전체 직책 체인을 간단하게 정리했다.
느낌이 이상하지 않아요? 사실 어떤 제품들은 지난번 제품에서 전달되었을 때 실행된 것이 아니라 데이터가 되돌아올 때 실행된 거예요. 예를 들어 인코딩, 디코딩 같은 거예요. 이 실현은consumer를 통해 이루어진 거예요. consumer는 전체 체인에 전달된다고 합니다.이를 실현하기 위해 필요한 Producer에서 데이터를 되돌릴 때의 차단을 다시 만들고 해당하는 처리를 한다. 예를 들어 캐시 Producer는 캐시가 없을 때 네트워크 데이터를 가져와야 한다. 이 절차를 진행하는 것이 무슨 의미가 있는가?사실 이 캐시 처리는 consumer 데이터가 리셋될 때 데이터를 캐시하는 것입니다. 이 방법은 새로운 consumer를 만들어서 새로운 consumer를 다음 Producer로 전달하고, 최종 데이터는 이 새로운 consumer를 통해 되돌려줍니다. 데이터를 얻은 후에 캐시 처리를 하고, 처리된 consumer를 통해 되돌려줍니다.나는 개인적으로 이런 디자인이 매우 교묘해서 모든 프로듀서를 연결시킨다고 생각한다.
다음은 이전 Producer에서 캐시 프로세스를 통해 수행된 작업입니다.
@Override
public void produceResults(final Consumer<CloseableReference<T>> consumer, final ProducerContext producerContext) {
final ProducerListener listener = producerContext.getListener();
final String requestId = producerContext.getId();
listener.onProducerStart(requestId, getProducerName());
final K cacheKey = getCacheKey(producerContext.getImageRequest());
CloseableReference<T> cachedReference = mMemoryCache.get(cacheKey, null);
if (cachedReference != null) {//
boolean shouldStartNextProducer = shouldStartNextProducer(cachedReference);
if (!shouldStartNextProducer) {// produder , producer
listener.onProducerFinishWithSuccess(requestId, getProducerName(),
listener.requiresExtraMap(requestId) ? ImmutableMap.of(CACHED_VALUE_FOUND, "true") : null);
}
consumer.onNewResult(cachedReference, !shouldStartNextProducer);
cachedReference.close();
if (!shouldStartNextProducer) {
return;
}
}
// ,
Consumer<CloseableReference<T>> consumerOfNextProducer;// , ,
if (!shouldCacheReturnedValues()) {// , ,
consumerOfNextProducer = consumer;
} else {
// consumer ,
consumerOfNextProducer = new BaseConsumer<CloseableReference<T>>() {
@Override
public void onNewResultImpl(CloseableReference<T> newResult, boolean isLast) {
CloseableReference<T> cachedResult = null;//newResult ,
if (newResult != null && shouldCacheResult(newResult, cacheKey, isLast)) {
cachedResult = mMemoryCache.cache(cacheKey, newResult);
}
if (cachedResult != null) {// consumer
consumer.onNewResult(cachedResult, isLast);
cachedResult.close();
} else {
consumer.onNewResult(newResult, isLast);
}
}
@Override
public void onFailureImpl(Throwable t) {
consumer.onFailure(t);
}
@Override
protected void onCancellationImpl() {
consumer.onCancellation();
}
};
}
listener.onProducerFinishWithSuccess(requestId, getProducerName(),
listener.requiresExtraMap(requestId) ? ImmutableMap.of(CACHED_VALUE_FOUND, "false") : null);
mNextProducer.produceResults(consumerOfNextProducer, producerContext);//
}
그래서 실제 자신의 직책을 수행하는 것은 데이터가 되돌아올 때 하는 것이고 다른 몇몇 제품도 비슷한 방법이다.
자, Producer의 절차는 대충 설명했습니다. 모든 Producer의 구체적인 실현은 말하지 않겠습니다. 너무 많아서 이 사고방식에 따라 보면 쉽게 이해할 수 있습니다.
전재는 출처를 밝혀 주십시오.http://blog.csdn.net/u014614038/article/details/51507236
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Asp와 XML로 상호작용하는 실례 원본XML은 표준 확장 언어로 미래 웹 프로그래밍의 표준이다. asp는 현재 널리 전해지는 웹 프로그래밍 언어 중의 하나이다. 그들 두 사람이 연합하여 역할을 발휘할 수 있을까?두부는 여기서 여러분에게 아주 간단한 As...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.