Glide 4.0源码分析(1)

来源:互联网 发布:联通网络整合营销包括 编辑:程序博客网 时间:2024/06/05 16:39

说明:
1、源码采用Glide4.0.0版本,和Glide3.7.0版本相比,用法和实现类变化都比较大。个人觉得在用法方面,Glide4.0提高了代码的可复用性。
2、在源码执行的过程中,遇到泛型,所调用的具体实现类可以通过Debug来确定到底是哪一个。
3、Glide源码很复杂,看了好多遍,Debug的好多遍才能大概了解执行流程

Glide用法:

 Glide.with(this).load(url) .into(imageView);

本文就从Glide加载图片的第一步开始:
Glide.with(),并返回一RequestManager对象。代码如下:

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

先看getRetriever()方法

 private static RequestManagerRetriever getRetriever(@Nullable Context context) {    // Context could be null for other reasons (ie the user passes in null), but in practice it will    // only occur due to errors with the Fragment lifecycle.    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).");    return Glide.get(context).getRequestManagerRetriever();  }

第9行Glide.get(context)通过单例模式返回一个Glide对象,而getRequestManagerRetriever()方法返回一个RequestManagerRetriever 对象,该对象是Glide的成员变量。
我们接着看RequestManagerRetriever的get方法;

  public RequestManager get(FragmentActivity activity) {    if (Util.isOnBackgroundThread()) {      return get(activity.getApplicationContext());    } else {      assertNotDestroyed(activity);      FragmentManager fm = activity.getSupportFragmentManager();      return supportFragmentGet(activity, fm, null /*parentHint*/);    }  }

如果是在后台线程调用的该方法,则把Application的Context当做参数传给get(Context context)函数,否则在第7行执行supportFragmentGet()方法,我们来看一下这个方法

private RequestManager supportFragmentGet(Context context, FragmentManager fm,      Fragment parentHint) {    SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);    RequestManager requestManager = current.getRequestManager();    if (requestManager == null) {      // TODO(b/27524013): Factor out this Glide.get() call.      Glide glide = Glide.get(context);      requestManager =          factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode());      current.setRequestManager(requestManager);    }    return requestManager;  }

给每一个Activity或者Fragment添加一个隐藏的Fragment和RequestManager,并把RequestManager返回。而这个添加的Fragment是Glide用来进行生命周期管理的。
以上就是Glide.with()大致执行流程,下面我们来看一下其中的一些细节。
先看Glide.get()方法:

   private static volatile Glide glide;  /**   * Get the singleton.   *   * @return the singleton   */  public static Glide get(Context context) {    if (glide == null) {      synchronized (Glide.class) {        if (glide == null) {          checkAndInitializeGlide(context);        }      }    }    return glide;  }

采用双重检验锁(DCL)的方式生成单例,注意glide变量需要用volatile关键字修饰。glide初始化的具体实现在checkAndInitializeGlide(context)方法中:

private static void checkAndInitializeGlide(Context context) {    // In the thread running initGlide(), one or more classes may call Glide.get(context).    // Without this check, those calls could trigger infinite recursion.    if (isInitializing) {      throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"          + " use the provided Glide instance instead");    }    isInitializing = true;    initializeGlide(context);    isInitializing = false;  }

判断是否正在初始化,如果不是则初始化,即调用initializeGlide(context)方法

@SuppressWarnings("deprecation")  private static void initializeGlide(Context context) {    Context applicationContext = context.getApplicationContext();    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();    List<GlideModule> manifestModules = Collections.emptyList();    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {      manifestModules = new ManifestParser(applicationContext).parse();    }    if (annotationGeneratedModule != null        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {      Set<Class<?>> excludedModuleClasses =          annotationGeneratedModule.getExcludedModuleClasses();      for (Iterator<GlideModule> iterator = manifestModules.iterator(); iterator.hasNext();) {        GlideModule current = iterator.next();        if (!excludedModuleClasses.contains(current.getClass())) {          continue;        }        if (Log.isLoggable(TAG, Log.DEBUG)) {          Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);        }        iterator.remove();      }    }    if (Log.isLoggable(TAG, Log.DEBUG)) {      for (GlideModule glideModule : manifestModules) {        Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());      }    }    RequestManagerRetriever.RequestManagerFactory factory =        annotationGeneratedModule != null            ? annotationGeneratedModule.getRequestManagerFactory() : null;    GlideBuilder builder = new GlideBuilder()        .setRequestManagerFactory(factory);    for (GlideModule module : manifestModules) {      module.applyOptions(applicationContext, builder);    }    if (annotationGeneratedModule != null) {      annotationGeneratedModule.applyOptions(applicationContext, builder);    }    Glide glide = builder.build(applicationContext);    for (GlideModule module : manifestModules) {      module.registerComponents(applicationContext, glide, glide.registry);    }    if (annotationGeneratedModule != null) {      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);    }    Glide.glide = glide;  }

这个方法被标记为deprecation,表示这个方法以后可能会被弃用,那么先看一下这个方法进行了哪些工作。
在第44行通过Builder模式创建一个Glide实例,44行之前是加载Glide一些自定义设置,在Glide4.0版本中,Glide自定义设置由原来的再Manifest文件中配置改成了使用注解的方式,为了兼容以前的版本这两种现在都可以使用,不过作者可能会在以后版本中移除Mainfest的方式,所以也是这个方法被标记为deprecation的原因。
我们具体来看一下builder.build(applicationContext)方法

public Glide build(Context context) {    if (sourceExecutor == null) {      //创建网络加载线程池      sourceExecutor = GlideExecutor.newSourceExecutor();    }    if (diskCacheExecutor == null) {      //创建读取硬盘缓存线程池      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();    }    if (memorySizeCalculator == null) {      //根据具体设备智能计算各个缓存池占内存大小      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();    }    if (connectivityMonitorFactory == null) {      //用来检查是否有网络连接权限      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();    }    if (bitmapPool == null) {      //创建Bitmap缓存池      int size = memorySizeCalculator.getBitmapPoolSize();      bitmapPool = new LruBitmapPool(size);    }    //TUDO暂时还没看懂这个的作用    if (arrayPool == null) {      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());    }    if (memoryCache == null) {      //创建内存缓存      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());    }    if (diskCacheFactory == null) {       //创建硬盘缓存      diskCacheFactory = new InternalCacheDiskCacheFactory(context);    }    if (engine == null) {      //创建图片加载引擎      engine = new Engine(memoryCache, diskCacheFactory, diskCacheExecutor, sourceExecutor,          GlideExecutor.newUnlimitedSourceExecutor());    }    //创建RequestManagerRetriever对象    RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(        requestManagerFactory);    return new Glide(        context,        engine,        memoryCache,        bitmapPool,        arrayPool,        requestManagerRetriever,        connectivityMonitorFactory,        logLevel,        defaultRequestOptions.lock());  }

这里进行了初始化了Glide工作需要一些组件,并传给了Glide的构造方法,这些都会在Glide.with(this).load(url).into(imageView)的后两步用到。

Glide.with()暂时就看了这么多。
总结:
每次我们调用Glide.with()方法,Glide会通过一个单例获取到一个RequestManagerRetriever对象,而通过RequestManagerRetriever 对象根据Context参数就可获取到每一个和Activity或者Fragment的关联的RequestManager对象,而RequestManager用来管理Activity或者Fragment中所有的图片加载请求 。
第二步请看Glide 4.0源码分析(2)

原创粉丝点击