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)
- Glide 4.0源码分析(1)
- Glide 4.0源码分析(2)
- Glide 4.0源码分析(3)
- Glide源码分析1 - 框架
- glide源码分析
- Glide 源码分析
- Glide源码分析 一
- Glide源码分析
- Glide源码分析
- Glide源码分析-生命周期管理
- Glide源码分析-下载图片
- Glide的源码分析<一>
- android开发-Glide源码分析
- Glide源码分析(二)——磁盘缓存实现
- Glide源码分析(四)——Registry机制
- Glide源码分析(五)——ModelLoader机制
- 深入理解Glide源码,分析之路(二):Glide的执行流程,史上最详细、易懂
- Glide源码分析3 -- 绑定Activity生命周期
- 关于 ioctl 详细信息
- 使用 poi 根据 word 模板生成 word 文件
- Angular4.x 引入第三方 JS
- 适用于STL泛型的归并(合并排序)排序算法设计
- mysql的merge存储引擎应用
- Glide 4.0源码分析(1)
- 排序算法---直接插入排序
- 构造排序二叉树,并按行从左到右输出
- MATLAB绘图
- 1
- linux部署web项目到tomcat下(图文详解)
- 数据结构与算法之栈
- SiteSucker使用记录
- 配置wamp