Glide源码(一)

Picasso,Glide,Fresco对比

上一篇我们分析了Picasso,这一篇我们来分析Glide源码的调用流程,目前主流的图片加载框架除了Picasso和Glide,还有Facebook开源的Fresco,有时间也将开一篇来分析。下面用一张表格来对3者进行对比,如下:


image.png

示例

 Glide.with( activity )
      .load( imageUrl )//指定加载路径
      .placeholder( R.mipmap.ic_launcher )//加载前默认图
      .error( R.mipmap.ic_launcher )//加载错误时显示的图片
      .override( 300, 300 )//指定图片大小
      .centerCrop()//缩放,太大会裁剪并填满整个控件
      .fitCenter()//缩放,会显示完整图片,但有可能不会填满整个控件
      .skipMemoryCache( true )//跳过内缓存,但仍会使用硬盘缓存
      .diskCacheStrategy( DiskCacheStrategy.NONE )//不进行磁盘缓存
      .diskCacheStrategy( DiskCacheStrategy.RESOURCE )//只缓存转换过后的图片
      .diskCacheStrategy( DiskCacheStrategy.ALL )//既缓存原始图片,也缓存转换过后的图片
      .diskCacheStrategy( DiskCacheStrategy.DATA )//只缓存原始图片
      .diskCacheStrategy( DiskCacheStrategy.AUTOMATIC )//根据图片资源自动选择一种缓存策略(默认选项)
      .priority( Priority.HIGH )//指定优先级,但没法保证一定按优先级加载
      .into( (ImageView) view );//显示目标

如示例所示,根据不同的需求场景,我们可以为Glide指定不同的配置。由于Glide源码非常庞大和复杂,因此,本篇只分析3个主要的调用流程,即:

  Glide.with( getApplicationContext() )
          .load( imageUrl )
          .into( (ImageView) view );

源码分析

public class Glide implements ComponentCallbacks2 {
  ......
  public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
  }

  
  public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }


public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }


 public static RequestManager with(@NonNull Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
  }

public static RequestManager with(@NonNull View view) {
    return getRetriever(view.getContext()).get(view);
  }

    ......

//获取RequestManagerRetriever 
 private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    Preconditions.checkNotNull(
        context,
        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
    //初始化Glide,并获取RequestManagerRetriever 
    return Glide.get(context).getRequestManagerRetriever();
  }
}

with根据不同的上下文参数,提供了多个重载方法,因为不同的上下文环境对图片加载的生命周期,会有不同的影响。

with方法将返回一个RequestManager ,而RequestManager 的获取,需要通过RequestManagerRetriever()这个检索器来构造,并且,一个上下文环境只持有一个检索器。

假设第一次调用,在获取RequestManagerRetriever检索器前,将先初始化Glide。如源码中所示,Glide.get(context)将初始化并返回Glide对象。

public class Glide implements ComponentCallbacks2 {

    //获取单例
  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      synchronized (Glide.class) {
        if (glide == null) {
          //初始化检查
          checkAndInitializeGlide(context);
        }
      }
    }
    return glide;
  }

  //初始化检查
  private static void checkAndInitializeGlide(@NonNull Context context) {
    if (isInitializing) {
      throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
          + " use the provided Glide instance instead");
    }
    isInitializing = true;
    initializeGlide(context);
    isInitializing = false;
  }

  //构造一个new GlideBuilder()并调用双参的重载方法
  private static void initializeGlide(@NonNull Context context) {
    initializeGlide(context, new GlideBuilder());
  }

  //初始化
  private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
          ......
    //构造Glide对象
    Glide glide = builder.build(applicationContext);
          ......
    //保存到静态成员中
    Glide.glide = glide;
  }

    .......
}

Glide通过双重检查锁方式,来初始化和构造单例对象。我们看到,在initializeGlide方法中new了一个GlideBuilder,它用来构建Glide对象,并将对象保存到静态成员变量glide 中。我们看build方法如何构建。

public final class GlideBuilder {

    ......

  Glide build(@NonNull Context context) {
    // 创建资源加载请求器,是一个线程池,用于加载源数据(URL等)
    if (sourceExecutor == null) {
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }
  //查找磁盘缓存的线程池
    if (diskCacheExecutor == null) {
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }
    //动画执行的线程池
    if (animationExecutor == null) {
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }
  // 内存计算器
    if (memorySizeCalculator == null) {
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }
   // 网络状态检测器
    if (connectivityMonitorFactory == null) {
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

  //Bitmap复用池
    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }

   // 数组资源缓存池
    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    //用于缓存加载完成和显示的图片数据资源
    if (memoryCache == null) {
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }
   // 磁盘缓存器,默认为 APP 内部私密目录
    if (diskCacheFactory == null) {
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }
  
  // 图片加载引擎,用于执行图片加载请求驱动
    if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              GlideExecutor.newAnimationExecutor(),
              isActiveResourceRetentionAllowed);
    }

// 构建一个请求监听器列表
    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

  //构建RequestManager的检索器
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

  //构建Glide
    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptions.lock(),
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled);
  }

buid方法构建了许多池子,同时生成上面RequestManager的检索器,在最后构建Glide时将所有参数传入。 Glide 的构造方法代码量非常多,故省略大量代码,只显示核心逻辑。

Glide(
    @NonNull Context context,
    @NonNull Engine engine,
    @NonNull MemoryCache memoryCache,
    @NonNull BitmapPool bitmapPool,
    @NonNull ArrayPool arrayPool,
    @NonNull RequestManagerRetriever requestManagerRetriever,
    @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
    int logLevel,
    @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
    @NonNull Map, TransitionOptions> defaultTransitionOptions,
    @NonNull List> defaultRequestListeners,
    boolean isLoggingRequestOriginsEnabled,
    boolean isImageDecoderEnabledForBitmaps,
    int hardwareBitmapFdLimit) {

    // 赋值
  this.engine = engine;
  this.bitmapPool = bitmapPool;
  this.arrayPool = arrayPool;
  this.memoryCache = memoryCache;
  this.requestManagerRetriever = requestManagerRetriever;
  this.connectivityMonitorFactory = connectivityMonitorFactory;
  this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;

  final Resources resources = context.getResources();

  // 新建注册器
  registry = new Registry();
  registry.register(new DefaultImageHeaderParser());
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
    registry.register(new ExifInterfaceImageHeaderParser());
  }

  List imageHeaderParsers = registry.getImageHeaderParsers();

  // 创建解码器
  ByteBufferGifDecoder byteBufferGifDecoder =
      new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);
  ResourceDecoder parcelFileDescriptorVideoDecoder =
      VideoDecoder.parcel(bitmapPool);

  ResourceDecoder byteBufferBitmapDecoder;
  ResourceDecoder streamBitmapDecoder;
  if (isImageDecoderEnabledForBitmaps && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    streamBitmapDecoder = new InputStreamBitmapImageDecoderResourceDecoder();
    byteBufferBitmapDecoder = new ByteBufferBitmapImageDecoderResourceDecoder();
  } else {
    Downsampler downsampler =
        new Downsampler(
            registry.getImageHeaderParsers(),
            resources.getDisplayMetrics(),
            bitmapPool,
            arrayPool);
    byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
    streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
  }

  ResourceDrawableDecoder resourceDrawableDecoder = new ResourceDrawableDecoder(context);
  // 创建数据转换器
  ResourceLoader.StreamFactory resourceLoaderStreamFactory =
      new ResourceLoader.StreamFactory(resources);
  ResourceLoader.UriFactory resourceLoaderUriFactory = new ResourceLoader.UriFactory(resources);
  ResourceLoader.FileDescriptorFactory resourceLoaderFileDescriptorFactory =
      new ResourceLoader.FileDescriptorFactory(resources);
  ResourceLoader.AssetFileDescriptorFactory resourceLoaderAssetFileDescriptorFactory =
      new ResourceLoader.AssetFileDescriptorFactory(resources);
  BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);

  // 创建转码器
  BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
  GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();

  ContentResolver contentResolver = context.getContentResolver();

  // 注册各个类型的解码器和编码器
  registry
      .append(ByteBuffer.class, new ByteBufferEncoder())
      .append(InputStream.class, new StreamEncoder(arrayPool))

      ......

      .register(
          Drawable.class,
          byte[].class,
          new DrawableBytesTranscoder(
              bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))
      .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);

  // 创建图片显示目标对象工厂
  ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
  // 创建 GlideContext 对象,注意传入的参数
  glideContext =
      new GlideContext(
          context,
          arrayPool,
          registry,
          imageViewTargetFactory,
          defaultRequestOptionsFactory,
          defaultTransitionOptions,
          defaultRequestListeners,
          engine,
          isLoggingRequestOriginsEnabled,
          logLevel);
}

构造方法主要是初始化模型转换器、解码器、转码器和编码器,并对各种类型在注册表进行注册。Glide的整个加载流程将经历:model(数据源)-->data(转换数据)-->decode(解码)-->transformed(缩放)-->transcoded(转码)-->encoded(编码保存到本地),所以在构造方法里初始化这些对象,是为Gilde后续的加载流程做准备的。

回到一开始的width方法。在GlideBuilder 中,已经创建好了RequestManagerRetriever检索器 ,RequestManagerRetriever 将通过get方法来获取RequestManager。

public class RequestManagerRetriever implements Handler.Callback {

      ......
  private volatile RequestManager applicationManager;
  public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
    this.factory = factory != null ? factory : DEFAULT_FACTORY;
    handler = new Handler(Looper.getMainLooper(), this /* Callback */);
  }
      ......
  //Application上下文环境
  private RequestManager getApplicationManager(@NonNull Context context) {
     if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
         Glide glide = Glide.get(context.getApplicationContext());
          //新建ApplicationLifecycle()和EmptyRequestManagerTreeNode
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }
    return applicationManager;
  }

//获取RequestManager 
  public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    //在主线程中,并且上下文不是Application
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      //对3种上下文进行判断
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }

    return getApplicationManager(context);
  }

//工厂接口
 public interface RequestManagerFactory {
    @NonNull
    RequestManager build(
        @NonNull Glide glide,
        @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode,
        @NonNull Context context);
  }


private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
    @NonNull
    @Override
    public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
      return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    }
  };
}

在构造RequestManagerRetriever时,倘若没有设置RequestManagerFactory工厂,那么将使用默认的匿名内部类DEFAULT_FACTORY 来构造RequestManager。

RequestManagerRetriever的get方法主要分2种情况,其中子线程和Application上下文环境最为简单,它将使用Application为上下文,构建RequestManager,并且由源码所示,RequestManager也是一个单例,也就是说,一种上下文只有一个RequestManagerRetriever检索器,也只有一个RequestManager对象。

而其他上下文情况,最终都会以Activity为上下文,调用参数为Activity的get方法,我们继续分析,看以Activity为上下文的调用过程和以Application为上下文的情况有什么不同。


public class RequestManagerRetriever implements Handler.Callback {
  //Tag缓存
   static final String FRAGMENT_TAG = "com.bumptech.glide.manager";
  //map缓存
    final Map pendingRequestManagerFragments =
      new HashMap<>();
    ......

  public RequestManager get(@NonNull Activity activity) {
    //后台线程
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(
          activity, fm,  null, isActivityVisible(activity));
    }
  }

  //activity是否退出了
  private static boolean isActivityVisible(Activity activity) {
       return !activity.isFinishing();
  }


  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //获取一个空fragment
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    //获取RequestManager 
    RequestManager requestManager = current.getRequestManager();
    //为空则构建
    if (requestManager == null) {
       Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    //通过名为FRAGMENT_TAG的Tag获取
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    //空则从缓存中获取
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      //缓存空则新建
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        //Activity没退出
        if (isParentVisible) {
          //开启生命周期监听
          current.getGlideLifecycle().onStart();
        }
        //缓存起来
        pendingRequestManagerFragments.put(fm, current);
        //加到当前Activity
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        //发送ID_REMOVE_FRAGMENT_MANAGER消息清除缓存
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

  //消息回调移除缓存RequestManagerFragment 
  @Override
  public boolean handleMessage(Message message) {
    boolean handled = true;
    Object removed = null;
    Object key = null;
    switch (message.what) {
      case ID_REMOVE_FRAGMENT_MANAGER:
        android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
        key = fm;
        //从缓存移除
        removed = pendingRequestManagerFragments.remove(fm);
        break;
      case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
        FragmentManager supportFm = (FragmentManager) message.obj;
        key = supportFm;
        removed = pendingSupportRequestManagerFragments.remove(supportFm);
        break;
      default:
        handled = false;
        break;
    }
    if (handled && removed == null && Log.isLoggable(TAG, Log.WARN)) {
      Log.w(TAG, "Failed to remove expected request manager fragment, manager: " + key);
    }
    return handled;
  }


}

RequestManagerFragment 是一个空的Fragment,Glide正是通过它来监听Activity的生命周期,换句话说,当Activity的生命周期方法被回调,也就同时回调了Fragment(RequestManagerFragment )。

如源码中所示,如果RequestManagerFragment被添加到当前的Activity中,那么通过变量名FRAGMENT_TAG就可以获取到,那为什么还需要使用pendingSupportRequestManagerFragments这个Map来进行缓存,而添加到Activity后,又立即通过消息将其从Map中移除?

因为并发。以下面的代码为例:

Glide.with(activity).load(url1).into(imageView1); //request1
Glide.with(activity).load(url2).into(imageView2); //request2

Fragment添加是通过Handler消息队列操作的,而消息队列执行在主线程之后。假设request1创建RequestManagerFragment,并提交了事务,在RequestManagerFragment添加消息未执行,也就是说RequestManagerFragment未被添加到Acitivy中前,request2执行到fm.findFragmentByTag(FRAGMENT_TAG),current 将会为null,那么,如果不使用map来缓存,RequestManagerFragment又将实例化一个,也就意味着,当前Activity将出现重复添加RequestManagerFragment的情况。

由于移除消息在提交事务消息之后,等到移除消息执行时,后面的请求已经能通过FRAGMENT_TAG获取到RequestManagerFragment了,Map没有必要再继续缓存着,因此,从缓存移除,以避免内存泄漏和减少内存压力。

下面来看RequestManagerFragment是监听Activity生命周期做了哪些操作。

public class RequestManagerFragment extends Fragment {

  private final ActivityFragmentLifecycle lifecycle;

  public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }

public void onDetach() {
    super.onDetach();
    unregisterFragmentWithRoot();
  }


 @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }

  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    lifecycle.onDestroy();
    unregisterFragmentWithRoot();
  }

}

RequestManagerFragment 构造时构建了一个ActivityFragmentLifecycle 对象,它正是负责生命周期的回调。

class ActivityFragmentLifecycle implements Lifecycle {
   private final Set lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap());
  private boolean isStarted;
  private boolean isDestroyed;

  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);

    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.remove(listener);
  }

  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}
public interface Lifecycle {

  void addListener(@NonNull LifecycleListener listener);

  void removeListener(@NonNull LifecycleListener listener);
}

ActivityFragmentLifecycle 实现了Lifecycle 接口,通过addListener方法将LifecycleListener添加到集合中,当Activity生命周期被回调,将触发RequestManagerFragment对应的生命周期,也将触发ActivityFragmentLifecycle 遍历lifecycleListeners集合,回调每个LifecycleListener对应的方法。

public interface LifecycleListener {

  void onStart();

  void onStop();

  void onDestroy();
}

LifecycleListener接口定义了3个生命周期回调,它的LifecycleListener的实现类有许多个,其中就包括RequestManager类。

with方法分析完毕,总结一下它所做的工作:

  • 构造并初始化Gilde对象;
  • 在构建Gilde对象的过程中,构建RequestManagerRetriever检索器;
  • 检索器在上下文环境不是Application的情况下,会构建一个RequestManagerFragment 来监听页面的生命周期。
  • 构建RequestManager对象。Application环境下,RequestManagerRetriever持有RequestManager,非Application环境下,RequestManagerFragment持有RequestManager。

你可能感兴趣的:(Glide源码(一))