尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
react-native-fast-image 中移除内置 AppGlideModule:解决 Glide 单例冲突的 excludeAppGlideModule 实践
移动开发前端UI组件【免费下载链接】react-native-fast-image FastImage, performant React Native image component.项目地址https://gitcode.com/gh_mirrors/re/react-native-fast-image点击查看免费下载本篇围绕docs/app-glide-module.md这一专题展开当你的应用已经在使用 Glide 并注册了自己的AppGlideModule时如何安全地排除react-native-fast-image内置的AppGlideModule避免两者冲突。读完本文你将了解冲突的根源、官方修复开关excludeAppGlideModule的完整配置方法以及该开关在库源码中的具体实现机制——从build.gradle的源码集过滤逻辑到进度事件onProgress为何在排除后依然可用。背景Glide 的 AppGlideModule 单实例约束Glide 的模块体系中AppGlideModule有严格的单实例约束一个最终构建出的 Android 应用里Glide 注解处理器只会合并一个AppGlideModule的实现。因此任何以 AAR/源码形式引入的库如果自带AppGlideModule就必须提供关闭机制否则当宿主应用已有自己的AppGlideModule时就会产生冲突。react-native-fast-image的 Android 端确实自带了一个这样的模块。查看 FastImageGlideModule.java// We need an AppGlideModule to be present for progress events to work. GlideModule public final class FastImageGlideModule extends AppGlideModule { }这是一个空的AppGlideModule源码注释直接说明了它存在的唯一目的We need an AppGlideModule to be present for progress events to work进度事件的正常工作要求应用中至少存在一个AppGlideModule。这也是官方文档 app-glide-module.md 所针对的场景如果你的应用已经在用 Glide 且注册了自定义的AppGlideModule比如用于自定义磁盘缓存、注册解码器或替换 HTTP 栈你就需要prevent the inclusion of theAppGlideModulein this package防止这个包中的AppGlideModule被包含进构建。项目 README.md 也专门设了一节提醒Are you using Glide already using an AppGlideModule? (you might have problems if you dont read this)可见这是官方明确警告过的常见踩坑点。官方修复在应用层 build.gradle 设置 excludeAppGlideModule按照 app-glide-module.md 给出的方案在你的应用项目的android/build.gradle中添加如下配置project.ext { excludeAppGlideModule true }这一个开关即可让react-native-fast-image在参与你应用的构建时把内置的AppGlideModule从源码集中排除掉把AppGlideModule的名额让给你自己的模块。开关在库源码中的落地方式这个开关并非由 JS 层或运行时逻辑处理而是在库自身的 Gradle 构建脚本里生效。查看 android/build.gradledef safeExtGet(prop, fallback) { rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback }库通过safeExtGet从rootProject.ext读取宿主应用的扩展属性读不到则回退到默认值。excludeAppGlideModule的默认值是false即默认行为是把FastImageGlideModule编译进库。当你在应用中将其设为true时android/build.gradle 中的源码集配置会改变sourceSets { main { java { if (safeExtGet(excludeAppGlideModule, false)) { srcDir src exclude **/FastImageGlideModule.java } } } }也就是说该开关的工作方式是编译期的源码集过滤命中条件时显式声明srcDir src并用exclude **/FastImageGlideModule.java把 FastImageGlideModule.java 从待编译的 Java 源码中剔除。由于该文件根本不会参与编译Glide 注解处理器自然不会再发现这个AppGlideModule冲突随之消除。同样的safeExtGet机制也被用于库的其他构建参数例如compileSdkVersion、minSdkVersion、glideVersion默认4.12.0等见 android/build.gradle。这说明excludeAppGlideModule与这些参数遵循同一套宿主应用通过project.ext覆盖库默认值的约定配置方式上保持了一致性。顺带一提仓库中的示例应用 ReactNativeFastImageExample/android/build.gradle 并未设置excludeAppGlideModule因此它依赖的正是库内置的FastImageGlideModule——这正好演示了应用自己没有AppGlideModule时的默认路径。排除后进度事件为何不受影响一个自然的疑问是既然FastImageGlideModule存在的理由是进度事件需要AppGlideModule把它排除掉之后onProgress回调还能工作吗可以从源码结构看出答案。真正负责进度事件的并不是那个空的AppGlideModule而是 FastImageOkHttpProgressGlideModule.java它继承的是LibraryGlideModule而非AppGlideModuleGlideModule public class FastImageOkHttpProgressGlideModule extends LibraryGlideModule { private static final DispatchingProgressListener progressListener new DispatchingProgressListener(); Override public void registerComponents( NonNull Context context, NonNull Glide glide, NonNull Registry registry ) { OkHttpClient client OkHttpClientProvider .getOkHttpClient() .newBuilder() .addInterceptor(createInterceptor(progressListener)) .build(); OkHttpUrlLoader.Factory factory new OkHttpUrlLoader.Factory(client); registry.replace(GlideUrl.class, InputStream.class, factory); } // ... }LibraryGlideModule与AppGlideModule的合并规则不同库模块可以存在任意多个它们不会触发单实例冲突。该模块通过替换GlideUrl - InputStream的加载器给 OkHttp 客户端挂上一个拦截器在每次读取字节时统计bytesRead / contentLength再经由静态方法expect(key, listener)/forget(key)见 FastImageOkHttpProgressGlideModule.java把进度分发给 JS 侧的onProgress回调。因此排除FastImageGlideModule后负责拦截和派发进度的LibraryGlideModule依然在构建中onProgress事件链路完整保留你应用自己的AppGlideModule恰好满足了源码注释里AppGlideModule必须存在的前提进度事件的条件依然成立。换言之excludeAppGlideModule只是移除了一个占位的空实现不会削弱 FastImage 的下载进度、优先加载priority、预加载FastImage.preload等能力。配套检查Proguard 配置中的 AppGlideModule 规则如果你的应用启用了 Proguard/R8README.md 要求向android/app/proguard-rules.pro追加如下 keep 规则-keep public class com.dylanvann.fastimage.* {*;} -keep public class com.dylanvann.fastimage.** {*;} -keep public class * implements com.bumptech.glide.module.GlideModule -keep public class * extends com.bumptech.glide.module.AppGlideModule -keep public enum com.bumptech.glide.load.ImageHeaderParser$** { **[] $VALUES; public *; }注意其中两条与本文主题直接相关-keep public class * extends com.bumptech.glide.module.AppGlideModule保护的是你应用里自己的AppGlideModule。设置excludeAppGlideModule true之后构建产物中唯一的AppGlideModule就是它混淆裁剪时必须保留否则 Glide 在运行时找不到模块配置-keep public class * implements com.bumptech.glide.module.GlideModule覆盖所有GlideModule包括 FastImage 的FastImageOkHttpProgressGlideModule保证进度模块不被裁剪掉。这套规则与你是否排除内置模块相互独立但建议在启用excludeAppGlideModule的同一轮改动中一并核对。适用前提与小结场景是否需要设置excludeAppGlideModule true应用未直接使用 Glide也没有自己的AppGlideModule不需要保持默认false由库内置的FastImageGlideModule占位应用已有自定义AppGlideModule自管理磁盘缓存、自定义解码、替换网络栈等需要按 app-glide-module.md 在应用层android/build.gradle中设置使用 Proguard额外按 README.md 补充 keep 规则小结excludeAppGlideModule是react-native-fast-image为宿主应用已有AppGlideModule场景提供的官方逃生口。它的实现路径清晰——应用层通过project.ext置位库的 android/build.gradle 在编译期把 FastImageGlideModule.java 从源码集中排除而承担实际职责的进度模块 FastImageOkHttpProgressGlideModule.java 基于LibraryGlideModule不受排除影响。理解这条机制后你既能安全共存于自有 Glide 模块也不会误判为排除后进度回调失效。赞分享移动开发前端UI组件【免费下载链接】react-native-fast-image FastImage, performant React Native image component.项目地址https://gitcode.com/gh_mirrors/re/react-native-fast-image点击查看免费下载相关推荐FormKit终极指南10倍速构建Vue 3表单的完整解决方案FormKit终极指南10倍速构建Vue 3表单的完整解决方案 FormKit是专为Vue 3开发者设计的 终极表单构建框架 能够让你以10倍的速度创建高质前端UI组件react-native-fast-image 常见问题解决方案react native fast image 常见问题解决方案 项目基础介绍 react native fast image 是一个高性能的 React Na移动开发前端UI组件react-native-fast-image 项目推荐react native fast image 项目推荐 1. 项目基础介绍和主要编程语言 react native fast image 是一个高性能的 Re移动开发前端UI组件上一篇NX Optimizer终极Switch游戏性能优化工具从60帧到480帧的流畅飞跃下一篇如何利用Loomio进行高效的团队讨论与决策创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

揭秘源师兄Python IDE隐藏的游戏化玩法:做任务、绑邀请码领积分,学Python更有动力

揭秘源师兄Python IDE隐藏的游戏化玩法:做任务、绑邀请码领积分,学Python更有动力

揭秘源师兄Python IDE隐藏的游戏化玩法:做任务、绑邀请码领积分,学Python更有动力 【免费下载链接】PythonIDE 源师兄的专属Python IDE,深度适配源师兄生态,打造人机一体的编程体验。 项目地址: https://gitcode.com/yuanshixio…

📅 2026/9/25 3:36:11
迁移 MySQL 扩展:从 mysql_* 到 mysqli 与 PDO 的升级指南(php-the-right-way)

迁移 MySQL 扩展:从 mysql_* 到 mysqli 与 PDO 的升级指南(php-the-right-way)

文档教程 【免费下载链接】php-the-right-way An easy-to-read, quick reference for PHP best practices, accepted coding standards, and links to authoritative tutorials around the Web 项目地址: https://gitcode.com/gh_mirrors/ph/php-the-right-way 点击…

📅 2026/9/25 3:36:11
DETR目标检测实战:从二分图匹配到端到端训练全解析

DETR目标检测实战:从二分图匹配到端到端训练全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/25 3:36:11
MORE NEWS

更多资讯

📰

如何为 easy-loading-cj 添加第 28 种动画?从零实现新指示器的完整步骤

如何为 easy-loading-cj 添加第 28 种动画?从零实现新指示器的完整步骤 【免费下载链接】easy-loading-cj easy-loading提供多种 loading/Toast 动画加载效果 项目地址: https://gitcode.com/Cangjie-TPC/easy-loading-cj easy-loading-cj 是一个基于 Cangji…

📰

UC网盘直链解析原理:不登录下载的底层逻辑与实操

1. 从“转存才能下”说起:UC网盘的分享机制到底卡在哪经常用UC网盘的朋友大概率遇到过这种场景:朋友甩过来一个分享链接,你点开一看,页面提示要先登录账号、再转存到自己的网盘,然后才能下载。如果只是偶尔用一次&…

📰

从零理解Online Judge:OJ判题原理、平台选择与刷题排错全攻略

聊到“3.1 OJ”这个标题,我第一反应是:这是一个课程讲义里的章节号,大概率是某个程序设计课或者算法竞赛入门课里,专门讲 Online Judge(在线评测系统)的那一节课。我太熟悉这个场景了——老师刚教完基本语法…

📰

Qt QPalette配色机制详解:从原理到实战,彻底掌控控件颜色

Qt开发者绕不开的痛点,就是“默认控件实在太丑了”。不管是刚接触Qt的新手,还是写了几年业务代码的老手,面对灰蒙蒙的QPushButton、白底黑字的QLineEdit,都会冒出同一个念头:怎么让界面好看一点?市面上的方…

📰

Blender4.2 + CLI-Anything 建模批量工程环境部署记录(二):TaoToken 统一 Key 接入 Codex 与 BlenderMCP 的 config.toml 骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

B站视频接口批量抓取实战:视频列表与详情数据采集全指南

做内容运营和数据分析的人,迟早会遇到一个需求:批量拉取某个B站账号的视频列表和详情数据。可能是想把自己账号的投稿导出成表格做季度复盘,可能是想研究某个垂直领域头部UP主都在发什么选题,也可能是想给内部工具加一个稳定的数据…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬