Fresco의 Producer와 DataSource 간 어댑터 처리의 논리

14399 단어
4.3.1.2.1 Producer와 DataSource 간 어댑터 처리의 논리
프로그램 입구부터 얘기할게요.
CloseableProducerToDataSourceAdapter.create() 소스 코드
여기에 새 데이터 어댑터를 만들었을 뿐입니다. Closeable Producer To DataSource Adapter
  public static <T> DataSource<CloseableReference<T>> create(
      Producer<CloseableReference<T>> producer,
      SettableProducerContext settableProducerContext,
      RequestListener listener) {
    return new CloseableProducerToDataSourceAdapter<T>(
        producer, settableProducerContext, listener);
  }

계속 추적
Closeable ProducerToDataSourceAdapter 구성 과정
여기를 보니 특별한 조작을 하지 않고 부류 구조를 호출했을 뿐이다
  private CloseableProducerToDataSourceAdapter( Producer<CloseableReference<T>> producer, SettableProducerContext settableProducerContext, RequestListener listener) {
    super(producer, settableProducerContext, listener);
  }

Abstract Producer To DataSource Adapter 구조의 과정을 이렇게 오랫동안 찾았는데 드디어 핵심적인 논리를 찾았습니다. 여기서
어댑터 매개변수 초기화외부에 알리는 mRequestListener 요청이 시작되었음 생산자 Producer가 생산 데이터(핵심 논리) Protected Abstract Producer To DataSource Adapter(Producer, Settable Producer Context, Request Listener request Listener) {mSettable Producer Context = settable Producer Context; mRequest Listener = request Listener, mRequest Listener. on Request Start(settable Producer Context.com), mSettableProducerContext.getCallerContext(), mSettableProducerContext.getId(), mSettableProducerContext.isPrefetch()); producer.produceResults(createConsumer(), settableProducerContext); }
다른 무관한 부분은 우리가 먼저 관심을 두지 않고 핵심 논리의 조작을 직접 보았다
소비자 생성 생산자에게 생산 결과 전달우리 프로듀서를 열어봐.Producer Results, 이것은 단지 인터페이스일 뿐입니다. 이것은 사실 인터페이스를 위한 프로그래밍이잖아요. 우리의 요청이 어떤 조작을 하든지 간에 생산자에게 생산 작업을 시작하라고 통지할 뿐입니다.
앞에서 언급한 바와 같이 인터넷 데이터의 Producer가 어떻게 한 걸음 한 걸음 포장하고 만들어졌는지 우리는 첫 번째 인터넷에서 요청한 데이터를 참조한다. 그러나 관련된 Producer도 비교적 많다. 우리는 가장 먼저 처리한 Producer와 마지막으로 처리한 Producer와 중간에 대표적인 한두 개의 Producer를 골라서 설명한다.
다시 한 번 돌이켜 보면 Producer와 관련된 과정을 살펴보면 인터넷에서 데이터를 얻는 Producer는 한 걸음 한 걸음 포장하고 마지막에 Bitmap Memory Cache Get Producer에게 포장한다. 바로 메모리에서 얻은 Producer이다. 그래서 최종 Producer는 Bitmap Memory Cache Get Producer이다. 즉, 이 호출된 Producer가 바로 우리의 Bitmap Memory Cache Get Producer이다. 그러면 지금부터 Bitmap Memory Cachet Producer의 Producer Producer의 Producer Result에서 착수할 수 있다.
BitmapMemoryCacheGetProducer의 계승 체계
Producer

    --| BitmapMemoryCacheProducer

        --| BitmapMemoryCacheGetProducer

Bitmap Memory Cache Get Producer는 메모리에서 대응하는 데이터를 가져오는 것을 담당하는 Producer입니다. 원본 코드를 보고 Produce Result를 복사하는 방법이 없습니다. 기본 클래스의 Produce Result를 보십시오.
BitmapMemoryCacheProducer.produceResults() 소스
클래스의 이름에서 알 수 있듯이 이것은 메모리에 접근하는 제품일 뿐입니다. 따라서 제품 Result에 있을 때 자신의 메모리에서 먼저 가져와서 메모리에 존재하는지 확인합니다. 존재하면 알림consumer를 직접 얻으면 됩니다. 메모리에 존재하지 않으면 다음 프로세서에게 이 일을 처리하라고 알립니다. 다음 프로세서가 이 데이터를 처리한 후에 소비자에게 리셋을 알리는 방식입니다.후속 작업을 완성하는 것이 바로 처리된 데이터를 생성하는 것이다. 처리된 결과는 어떻게 메모리에 저장해야 합니까?키를 생성해서 메모리에 저장해야 합니다.
 @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());
    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);
      }
      consumer.onNewResult(cachedReference, isFinal);
      cachedReference.close();
      if (isFinal) {
        return;
      }
    }

    if (producerContext.getLowestPermittedRequestLevel().getValue() >=
        ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE.getValue()) {
      listener.onProducerFinishWithSuccess(
          requestId,
          getProducerName(),
          listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
      consumer.onNewResult(null, true);
      return;
    }

    Consumer<CloseableReference<CloseableImage>> wrappedConsumer = wrapConsumer(consumer, cacheKey);
    listener.onProducerFinishWithSuccess(
        requestId,
        getProducerName(),
        listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);
    mNextProducer.produceResults(wrappedConsumer, producerContext);
  }

소비자들은 이 메아리를 어떻게 처리할까요? Bitmap Memory Cache Producer.wrapConsumer () 소스
 protected Consumer<CloseableReference<CloseableImage>> wrapConsumer(
      final Consumer<CloseableReference<CloseableImage>> consumer,
      final CacheKey cacheKey) {
    return new DelegatingConsumer<
        CloseableReference<CloseableImage>,
        CloseableReference<CloseableImage>>(consumer) {
      @Override public void onNewResultImpl(CloseableReference<CloseableImage> newResult, boolean isLast) {
        // ignore invalid intermediate results and forward the null result if last
        if (newResult == null) {
          if (isLast) {
            getConsumer().onNewResult(null, true);
          }
          return;
        }
        // stateful results cannot be cached and are just forwarded
        if (newResult.get().isStateful()) {
          getConsumer().onNewResult(newResult, isLast);
          return;
        }
        // if the intermediate result is not of a better quality than the cached result,
        // forward the already cached result and don't cache the new result.
        if (!isLast) {
          CloseableReference<CloseableImage> currentCachedResult = mMemoryCache.get(cacheKey);
          if (currentCachedResult != null) {
            try {
              QualityInfo newInfo = newResult.get().getQualityInfo();
              QualityInfo cachedInfo = currentCachedResult.get().getQualityInfo();
              if (cachedInfo.isOfFullQuality() || cachedInfo.getQuality() >= newInfo.getQuality()) {
                getConsumer().onNewResult(currentCachedResult, false);
                return;
              }
            } finally {
              CloseableReference.closeSafely(currentCachedResult);
            }
          }
        }
        // cache and forward the new result
        CloseableReference<CloseableImage> newCachedResult =
            mMemoryCache.cache(cacheKey, newResult);
        try {
          if (isLast) {
            getConsumer().onProgressUpdate(1f);
          }
          getConsumer().onNewResult(
              (newCachedResult != null) ? newCachedResult : newResult, isLast);
        } finally {
          CloseableReference.closeSafely(newCachedResult);
        }
      }
    };
  }

여기서 프록시 디자인 모델을 사용했습니다. 왜냐하면 모든 Producer는 consumer의 방법을 사용하지만 서로 다른 Producer는 기존의 consumer를 바탕으로 자신의 논리를 처리해야 하기 때문입니다. 여기는요?원래consumer를 에이전트하고 호출할 때 자신의 논리를 처리한 다음에 원래consumer와 관련된 방법을 호출하면 됩니다.
여기서 우리는 소비자들이 새로운 결과를 낼 때 이 결과를 캐시하는 것을 보았다. 그러나 이것은 기본 클래스인 Bitmap Memory Cache Producer의 wrap Consumer의 방법일 뿐이다. 이 실현 클래스인 Bitmap Memory Cache Get Producer는 메모리를 얻는 데 사용될 뿐이기 때문에 메모리 캐시에 관여하지 않고 얻는 것일 뿐이다. 그래서 Bitmap Memory Cache Get Producer의 wrap Consumer는 되돌아오는 방법 중의 consumer일 뿐이다.
이 메모리 캐시 제품들을 보고 나서 마지막 제품들, 즉 네트워크 데이터 획득과 관련된 제품들: Network Fetch Producer를 살펴보겠습니다.

좋은 웹페이지 즐겨찾기