Glide加载图片流程(Part One)

Android图片加载框架最全解析(一),Glide的基本用法 !最后放上一个大概的Android学习方向及思路(详细的内容太多了~),提供给大家:对于程序员来说,要学习的知识内容、技术有太多太多,这里就先放上一部分,其他的内容有机会在后面的文章向大家呈现出来,不过我自己所有的学习资料都整理成了一个文档,一直在不断学习,希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!Android架构师之路很漫长,一起共勉吧! 阅读详情

由于项目的需要,这几天对Glide的执行过程做了简单的了解,希望对想了解Glide基本用法的朋友能有所帮助。

注意

  • 此系列博客基于Glide V3.7.0版本源码

  • 这里假设朋友们能够在Android Studio中正确引入Glide相关的依赖,如果有不懂的朋友,请参考官方文档引入依赖。


为了让朋友们尽快的了解Glide加载图片的流程,我们就从最简单的方式入手。请看如下代码:

ImageView fullscreenView = (ImageView) findViewById(R.id.fullscreen_view);
String imageUrl = "http://image.url.com";
Glide.with(this)
     .load(imageUrl)
     .into(fullscreenView);

代码清单1-1

使用Glide加载图片就是这么简单!!!

然而,简单的背后往往隐藏了太多的未知数,那么现在我们就来看看这几行简单代码背后究竟隐藏了哪些奇妙的东西。现在就和博主一起开启Glide的学习之旅吧 :)

一、with(this)

在上述代码清单1-1中,我是在FragmentActivity子类中调用了Glide的with方法,SO这里的this即是指FragmentActivity的子类实例。我们点击查看其源码,如下:

public static RequestManager with(FragmentActivity activity) {
    RequestManagerRetriever retriever = RequestManagerRetriever.get();
    return retriever.get(activity);
}

首先获取一个RequestManagerRetriever实例,通过该实例得到RequestManager对象。我们现在进入RequestManagerRetriever#get(FragmentActivity)方法中来具体看看RequestManager的获取过程:

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

我们只考虑常规情况下使用的场景(不考虑缓存等情况,后文与此相同),由上面的代码,我们很容易定位到supportFragmentGet方法:

 RequestManager supportFragmentGet(Context context, FragmentManager fm) {
        SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
        RequestManager requestManager = current.getRequestManager();
        if (requestManager == null) {
            requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

由于我们是初次调用Glide加载图片,所以这里会创建一个新的RequestManager实例,并存入SupportRequestManagerFragmentcurrent实例中。传入RequestManager对象中的LifecycleRequestManagerTreeNode我们后面再说。这里需要注意的是,在创建RequestManager对象时,默认创建了一个RequestTracker对象和OptionsApplier对象,以及我们的Glide对象。

我们进入到RequestManager的构造函数中,定位到glide实例的获取过程:

  RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
            RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
        this.context = context.getApplicationContext();
        this.lifecycle = lifecycle;
        this.treeNode = treeNode;
        this.requestTracker = requestTracker;
        this.glide = Glide.get(context);
        this.optionsApplier = new OptionsApplier();

        //省略其它无关代码
        ...........................
        ...........................
    }

在上述代码中,我们顺藤摸瓜,来到Glide类的get方法中:

 public static Glide get(Context context) {
        if (glide == null) {
            synchronized (Glide.class) {
                if (glide == null) {
                    Context applicationContext = context.getApplicationContext();
                    List<GlideModule> modules = new ManifestParser(applicationContext).parse();

                    GlideBuilder builder = new GlideBuilder(applicationContext);
                    for (GlideModule module : modules) {
                        module.applyOptions(applicationContext, builder);
                    }
                    glide = builder.createGlide();
                    for (GlideModule module : modules) {
                        module.registerComponents(applicationContext, glide);
                    }
                }
            }
        }

        return glide;
    }

在获取Glide的实例过程中,我们看到Glide会从AndroidManifest.xml文件中查询我们注册的GlideModule。同时将GlideBuilderGlide的实例传入我们注册的GlideModule的对应方法中。由此我们可以了解到,如果想预先控制Glide的一些行为,可以在我们的GlideModuleapplyOtionsregisterComponents方法中做控制。

接下来我们继续查看GlideBuildercreateGlide方法,直接定位到方法的最后一行:

new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);

好了,重头戏该上演了,我们来看看Glide类的构造函数:

Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
        this.engine = engine;
        this.bitmapPool = bitmapPool;
        this.memoryCache = memoryCache;
        this.decodeFormat = decodeFormat;
        loaderFactory = new GenericLoaderFactory(context);
        mainHandler = new Handler(Looper.getMainLooper());
        bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);

        dataLoadProviderRegistry = new DataLoadProviderRegistry();

        StreamBitmapDataLoadProvider streamBitmapLoadProvider =
                new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);
        dataLoadProviderRegistry.register(InputStream.class, Bitmap.class, streamBitmapLoadProvider);

        FileDescriptorBitmapDataLoadProvider fileDescriptorLoadProvider =
                new FileDescriptorBitmapDataLoadProvider(bitmapPool, decodeFormat);
        dataLoadProviderRegistry.register(ParcelFileDescriptor.class, Bitmap.class, fileDescriptorLoadProvider);

        ImageVideoDataLoadProvider imageVideoDataLoadProvider =
                new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
        dataLoadProviderRegistry.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider);

        GifDrawableLoadProvider gifDrawableLoadProvider =
                new GifDrawableLoadProvider(context, bitmapPool);
        dataLoadProviderRegistry.register(InputStream.class, GifDrawable.class, gifDrawableLoadProvider);

        dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
                new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));

        dataLoadProviderRegistry.register(InputStream.class, File.class, new StreamFileDataLoadProvider());

        register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
        register(File.class, InputStream.class, new StreamFileLoader.Factory());
        register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(int.class, InputStream.class, new StreamResourceLoader.Factory());
        register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
        register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
        register(String.class, InputStream.class, new StreamStringLoader.Factory());
        register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
        register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
        register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
        register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
        register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());

        transcoderRegistry.register(Bitmap.class, GlideBitmapDrawable.class,
                new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool));
        transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
                new GifBitmapWrapperDrawableTranscoder(
                        new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));

        bitmapCenterCrop = new CenterCrop(bitmapPool);
        drawableCenterCrop = new GifBitmapWrapperTransformation(bitmapPool, bitmapCenterCrop);

        bitmapFitCenter = new FitCenter(bitmapPool);
        drawableFitCenter = new GifBitmapWrapperTransformation(bitmapPool, bitmapFitCenter);
    }

这个方法相对比较长,但是理解起来较为简单。主要就是注册一些DataLoadProviderModelLoaderfactory以及几个Transcoder。为了更直观的理解和查询,我将它们罗列成下面三张表:(PS:这三张表对于理解Glide的加载流程很重要

表1-1 ModelType到DataType的映射表

ID ModelClass ResourceClass DataLoaderFactory
1 File ParcelFileDescriptor FileDescriptorFileLoader.Factory
2 File InputStream StreamFileLoader.Factory
3 int ParcelFileDescriptor FileDescriptorResourceLoader.Factory
4 int InputStream StreamResourceLoader.Factory
5 Integer ParcelFileDescriptor FileDescriptorResourceLoader.Factory
6 Integer InputStream StreamResourceLoader.Factory
7 String ParcelFileDescriptor FileDescriptorStringLoader.Factory
8 String InputStream StreamStringLoader.Factory
9 Uri ParcelFileDescriptor FileDescriptorUriLoader.Factory
10 Uri InputStream StreamUriLoader.Factory
11
Glide-源码详解 前言:之前的文章中,笔者介绍了很多Glide的使用方法,但是由于Glide框架封装得太好了,很多人在使用的时候,只是知其然不知其所以然,为了不要仅仅成为”cv工程师”,只会复制粘贴,所以这篇文章我们就一起来研究一下Glide的源码,看看Glide到底是怎么将一张图片加载出来的~ 阅读详情

相关推荐

实战指南 | IC模拟版图设计从零到精通,手把手带你掌握EDA工具与GDSII输出

本文提供了一份从零开始的IC模拟版图设计实战指南。详细介绍了如何搭建Linux环境、安装Cadence Virtuoso等EDA工具,并深入解析了PDK设计规则。通过手把手绘制CMOS反相器版图的实例,系统讲解了版图绘制、DRC/LVS验证、寄生参数提取、匹配设计以及ESD防护等核心技能,最终指导如何正确生成交付芯片制造厂的标准GDSII文件,帮助读者掌握完整的模拟版图设计流程

weixin_29214691的博客 345

(原创)详解Glide图片加载库常用方法

Glide图片加载库常用方法

Android_xiong_st的博客 1万+

【2026年华为秋招(AI)-2月4日-第一题(100分)- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

本文摘要:本文包含20道选择题,涵盖机器学习、线性代数、Transformer架构、概率统计等多个领域。题目涉及正交矩阵性质、Transformer注意力机制、聚类距离度量、ReAct框架、Softmax函数、混淆矩阵计算、Flash-Attention优化、位置编码、期望计算、归一化方法、矩阵迭代法、矩阵秩、大模型架构、神经网络推理、泊松流性质、SVM核函数以及聚类算法等知识点。每道题均提供解析,帮助理解核心概念和解题思路。

m0_73659489的博客 100

Glide加载图片

使用Glide加载图片,默认情况下在内存中缓存该图片。这样的情况下如果我们保存头像在某个路径,当再次更换头像时可能由于缓存问题,UI上更新的不及时。1、不使用缓存 (该方法不推荐,如果调用方法n次会闪烁n次,不友好)如果我们希望当图片路径不变,图片改变时能够及时刷新有如下方法调用。2、使用签名 (推荐使用)

iOS野狼的专栏 2336

Android图片加载框架最全解析(一)Glide的基本用法

找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。多练。(视频优势是互动感强,容易集中注意力)你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。下面资料部分截图是我花费几个月时间整理的,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

2401_83329718的博客 1017

Glide加载图片流程Part Two)之缓存流程分析

承接上文,我们简单了解了Glide加载图片流程,在这篇博文中,我们就来了解下Glide是如何缓存图片的。在上篇博文中我们知道,在初始化Glide对象时,GlideBuilder为我们配置了默认的缓存机制:Glide createGlide() { if (sourceService == null) { final int cores = Math.max(

行者录 873

Android图片压缩上传(整体压缩VS单张压缩)

最近的项目中图片上传时遇到了anr的情况,下面看一下bugly上的错误 主要说的是图片上传多张时先进行压缩,此时压缩超时,上报anr,针对这种情况采取了遍历图片集合单张上传,接下来会逐一介绍整体上传和单张上传的代码部分,下面两张gif图是展示单张和整体上传的效果。 单张压缩上传 整体压缩上传 da ...

lou_liang的博客 1583

第三方库写能看的文档有多重要?

最近赶项目,用到一些第三方库,发现一些看起来比原来的使用更好的库 例如加载图片,可以说几乎是我们必备的一个工具。 看下下面两个Android-Universal-Image-Loader和Facebook开源的一个Fresco 后者Fresco支持: (1) 支持流式,可以类似网页上模糊渐进式显示图片 (2) 对多帧动画图片支持更好,如 Gif、WebP (3) 更多样的显示,如圆角

Sanjay的专栏 978

part 3 App内存优化

Part 3 App内存优化 一 内存优化介绍及工具选择 1、内存优化介绍 内存问题 内存抖动:锯齿状、GC导致的卡顿 内存泄漏:可用内存减少、频繁GC 内存溢出:OOM、程序异常 2、工具选择 Memory Profiler 实时图表展示应用内存使用情况 识别内存泄漏、抖动等 提供捕获堆转储、强制GC以及跟踪内存分配的能力 总结:方便直观、线下平时使用 Memory Analyzer(M...

zsjlovesm521的博客 2058

Shared Element Transitions - Part 4: RecyclerView

原文地址:http://mikescamell.com/shared-element-transitions-part-4-recyclerview/在系列的第三节我们看到了如何在使用Picasso或Glide时使用共享元素过渡。在第四节,我们准备通过使用应用程序中热门的共享元素过渡组件RecyclerView来实现这个效果。Google Play Music是我在第一节中提到过的例子,当然还有很多

nightyk的专栏 1129

头像上传

上传文件 @Multipart @POST Observable post(@Url String url, @QueryMap Map&lt;String, Object&gt; map, @Part MultipartBody.Part file); RetrofitUtils public void post(String url, Map&lt;String, Object&gt; map...

jin020863的博客 277

doom3 render 部分1

渲染部分 渲染器真的好复杂的啊!!!! 这些东西除了专业人员和爱好者喜欢意外,基本上没有人的喜欢了,可是我认为udk并不像人们想的那样子就是威力无穷的东西了者也,但是ai的这个,这根本上是两码事情了者也 我觉得应该将quake3的很多东西加入过来了者也 这个确实是应用了很多quake3引擎里面的东西了者也! 渲染初始化 例如这个系统是

tailiangliang的专栏 4936

Exercises Dataset移动应用集成:iOS与Android开发终极指南

在健身应用开发领域,拥有一个全面、结构化的锻炼数据集是构建成功应用的关键。Exercises Dataset(锻炼数据集)为开发者提供了1324个健身锻炼项目的详细数据,支持6种语言,是iOS和Android应用开发的完美起点。本文将为您提供完整的移动应用集成指南,帮助您快速将这一强大的数据集整合到您的健身应用中。 ## 🔥 为什么选择Exercises Dataset? Exercises

gitblog_00912的博客 877

Android Studio3.0之后gradle.build中dependencie依赖由compile变为implementation

2017 年google 后,Android studio版本更新至3.0,更新中,连带着com.android.tools.build:gradle 工具也升级到了3.0.0,在3.0.0中使用了最新的Gralde 4.0 里程碑版本作为gradle的编译版本,该版本gradle编译速度有所加速,更加欣喜的是,完全支持Java8。当然,对于Kotlin的支持,在这个版本也有所体现,Kotli

qq_26585943的博客 5万+

Image 2生成技术揭秘:扩散模型如何重塑图像生成,Open Ai再次改变世界

综上所述,Image 2类图像生成技术的强大并非单一因素所致,而是一个系统工程原理优势扩散模型提供了稳定、高质量生成的数学基础,通过逐步去噪避免了传统方法的缺陷。效率突破潜在扩散模型将计算从高维像素空间转移到低维潜在空间,实现了效率的跃升,使高质量生成得以普及。语义理解跨模态对齐模型(如CLIP)打通了文本与图像的语义鸿沟,使模型能“听懂人话”。精细控制控制网络(如ControlNet)等技术的出现,赋予了用户前所未有的精确控制能力,将生成从“随机艺术”推进到“可控生产”。规模与数据。

热爱技术与前沿创新,深耕科技领域,在科创中精进自我;探索技术乐趣,分享技术干货与成长心得,以技术为伴,热爱生活,在科创与生活中双向成长。 492

生物观察:蜂鸟迁徙 及其他鸟类的翼-速度调控规律

without stop) to reach their wintering ground in Mexico and central America. They have to rely on favorable weather conditions and their own incredible endurance to complete these overwater flights. (注:并非所有。即使身体放平,扑动平面仍水平。

Sineey223的博客 492

Reflector反编译9.0.2

reflector.exe9.0.2中文版是一款专业的.NET反编译软件。reflector.exe可以分析程序集并向你展示它的所有秘密。.NET 框架向全世界引入了可用来分析任何基于 .NET 的代码(无论它是单个类还是完整的程序集)的反射概念。反射还可以用来检索有关特定程序集中包含的各种类、方法和属性的信息。无需升级

下一篇: Glide加载图片流程(Part Two)之缓存流程分析
iXinng
博客等级 码龄11年 1粉丝 2原创
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值