Glide之Registry、EncoderRegistry、Encoder分析

这块内容比较简单,主要是存(注册)和取

看一下注册:

    registry
        .append(ByteBuffer.class, new ByteBufferEncoder())
        .append(InputStream.class, new StreamEncoder(arrayPool))

就这两个,ByteBufferEncoder和StreamEncoder是Encoder的实现类

  public <Data> Registry append(@NonNull Class<Data> dataClass, @NonNull Encoder<Data> encoder) {
    encoderRegistry.append(dataClass, encoder);
    return this;
  }

EncoderRegistry中有个list,放进去

private final List<Entry<?>> encoders = new ArrayList<>();
  
public synchronized <T> void append(@NonNull Class<T> dataClass, @NonNull Encoder<T> encoder) {
    encoders.add(new Entry<>(dataClass, encoder));
  }

看一下怎么取:

  SourceGenerator 类,对请求回来的InputStream缓存

  private void cacheData(Object dataToCache) {
    long startTime = LogTime.getLogTime();
    try {
      //看这句话
      Encoder<Object> encoder = helper.getSourceEncoder(dataToCache);
      DataCacheWriter<Object> writer =
          new DataCacheWriter<>(encoder, dataToCache, helper.getOptions());
      originalKey = new DataCacheKey(loadData.sourceKey, helper.getSignature());
      helper.getDiskCache().put(originalKey, writer);
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(
            TAG,
            "Finished encoding source to cache"
                + ", key: "
                + originalKey
                + ", data: "
                + dataToCache
                + ", encoder: "
                + encoder
                + ", duration: "
                + LogTime.getElapsedMillis(startTime));
      }
    } finally {
      loadData.fetcher.cleanup();
    }

    sourceCacheGenerator =
        new DataCacheGenerator(Collections.singletonList(loadData.sourceKey), helper, this);
  }
DecodeHelper 类  
<X> Encoder<X> getSourceEncoder(X data) throws Registry.NoSourceEncoderAvailableException {
    return glideContext.getRegistry().getSourceEncoder(data);
  }
Registry 类  

  @NonNull
  @SuppressWarnings("unchecked")
  public <X> Encoder<X> getSourceEncoder(@NonNull X data) throws NoSourceEncoderAvailableException {
    Encoder<X> encoder = encoderRegistry.getEncoder((Class<X>) data.getClass());
    if (encoder != null) {
      return encoder;
    }
    throw new NoSourceEncoderAvailableException(data.getClass());
  }
EncoderRegistry类,从list中取出对应的Encoder
  
  @Nullable
  public synchronized <T> Encoder<T> getEncoder(@NonNull Class<T> dataClass) {
    for (Entry<?> entry : encoders) {
      if (entry.handles(dataClass)) {
        return (Encoder<T>) entry.encoder;
      }
    }
    return null;
  }

主要是StreamEncoder,我们分析一下这个类

package com.bumptech.glide.load.model;

import android.util.Log;
import androidx.annotation.NonNull;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * An {@link com.bumptech.glide.load.Encoder} that can write an {@link java.io.InputStream} to disk.
 */
public class StreamEncoder implements Encoder<InputStream> {
  private static final String TAG = "StreamEncoder";
  private final ArrayPool byteArrayPool;

  public StreamEncoder(ArrayPool byteArrayPool) {
    this.byteArrayPool = byteArrayPool;
  }

  @Override
  public boolean encode(@NonNull InputStream data, @NonNull File file, @NonNull Options options) {
    byte[] buffer = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class);
    boolean success = false;
    OutputStream os = null;
    try {
      os = new FileOutputStream(file);
      int read;
      while ((read = data.read(buffer)) != -1) {
        os.write(buffer, 0, read);
      }
      os.close();
      success = true;
    } catch (IOException e) {
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Failed to encode data onto the OutputStream", e);
      }
    } finally {
      if (os != null) {
        try {
          os.close();
        } catch (IOException e) {
          // Do nothing.
        }
      }
      byteArrayPool.put(buffer);
    }
    return success;
  }
}

很简单,就是把InputStream写入File里面,其中用到了ArrayPool,这个单独分析

发布了189 篇原创文章 · 获赞 25 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/lizhongyisailang/article/details/104161307
今日推荐