Expo项目构建APK后新图片未展示,是移动端开发中比较常见的问题。很多开发者在开发阶段使用 Expo Go 测试时一切正常,但执行 APK 打包并安装到真实设备后,新增的图片资源却无法显示,甚至出现图片加载失败、空白占位、找不到资源等情况。
这类问题通常不是代码逻辑错误,而是 Expo 构建流程、静态资源管理、缓存机制以及图片引用方式导致的。了解 Expo 对资源的处理方式,可以快速定位并解决 APK 中图片无法展示的问题。
一、检查图片是否正确加入项目资源
Expo 项目中的图片属于静态资源,构建 APK 时会根据代码引用关系将资源打包进去。如果图片没有被正确引用,Expo 可能不会将它加入最终安装包。
例如:
JavaScriptimport { Image } from 'react-native';source={require('./assets/images/logo.png')} style={{width:100,height:100}} />
这种方式会被 Expo 自动识别,并在构建时加入 APK。
而以下方式可能存在问题:
JavaScriptsource={{uri:'./assets/images/logo.png'}} />
或者:
JavaScriptconst img = './assets/images/logo.png';source={{uri: img}} />
这种动态字符串路径不会被 Metro 打包器识别,开发环境可能因为本地文件存在而显示,但生成 APK 后资源并不存在。
因此,静态图片建议使用 require() 引入。
二、确认图片文件名称大小写是否一致
Android 系统对文件路径大小写敏感,而部分开发环境(例如 Windows)默认不区分大小写。
例如项目中真实文件:
assets/images/banner.png
代码:
JavaScriptrequire('./assets/images/Banner.png')
在 Windows 环境中可能正常运行,但 APK 安装到 Android 手机后会加载失败。
检查以下内容:
-
图片名称大小写
-
文件夹名称大小写
-
后缀名是否一致
例如:
正确:
JavaScriptrequire('./assets/images/user_avatar.png')
错误:
JavaScriptrequire('./assets/images/User_Avatar.PNG')
开发阶段最好统一使用小写文件名,避免跨平台问题。
三、清理 Expo 和 Metro 缓存重新构建
Expo 会缓存资源信息,如果新增图片后直接重新打包,可能仍然使用旧缓存,导致新图片没有进入 APK。
可以执行:
Bashnpx expo start -c
其中:
-c
表示清除 Metro 缓存。
如果使用 EAS Build 构建 APK,也建议重新执行:
Basheas build --clear-cache
然后重新生成安装包。
完整流程:
Bashnpx expo start -c eas build -p android
安装新的 APK 测试。
四、检查 app.json 或 app.config.js 配置
部分 Expo 项目会通过配置文件限制资源目录。
例如:
JSON{ "expo": { "assetBundlePatterns": [ "**/*" ] } }
如果项目中修改过资源配置,需要确保图片目录包含在打包范围内。
常见错误:
JSON{ "expo": { "assetBundlePatterns": [ "assets/images/*" ] } }
如果新增图片放到了:
assets/icons/
那么构建时可能不会被包含。
推荐配置:
JSON{ "expo": { "assetBundlePatterns": [ "**/*" ] } }
这样可以确保项目资源全部加入构建包。
五、避免使用动态路径加载本地图片
很多开发者会根据业务数据动态拼接图片路径:
JavaScriptconst imageName = 'test.png';source={require(`./assets/${imageName}`)} />
这种写法无法正常工作,因为 Metro Bundler 在编译阶段无法确定具体文件。
解决方案是建立图片映射:
JavaScriptconst images = { test: require('./assets/test.png'), logo: require('./assets/logo.png') };source={images.test}/>
这样 Expo 可以提前分析所有资源,并加入 APK。
六、确认图片是否真的进入APK
如果怀疑构建过程没有包含图片,可以检查 APK 文件。
APK 本质上是 ZIP 压缩包,可以修改后缀:
app-release.apk
改为:
app-release.zip
然后解压查看。
重点检查:
assets/
目录。
如果图片不存在,说明构建阶段没有打包进去,需要检查:
-
图片引用方式
-
assetBundlePatterns 配置
-
Metro 缓存
如果图片存在,则可能是运行时路径或者代码问题。
七、React Native Image缓存导致旧图片显示
如果图片名称没有变化,只是替换了图片内容,例如:
旧:
logo.png
替换:
logo.png
Android 设备可能仍然显示缓存中的旧图片。
解决方式:
方法一:修改图片名称
例如:
logo_v2.png
重新引用:
JavaScriptsource={require('./assets/logo_v2.png')} />
这是最简单可靠的方法。
方法二:添加缓存控制
如果使用网络图片:
JavaScriptsource={{ uri:'https://example.com/logo.png', cache:'reload' }} />
或者:
JavaScriptsource={{ uri:`https://example.com/logo.png?v=2` }} />
通过修改 URL 参数强制刷新缓存。
八、Expo Asset资源加载方式优化
对于大量图片资源,可以使用 Expo 提供的 Asset 模块。
安装:
Bashnpx expo install expo-asset
使用:
JavaScriptimport { Asset } from 'expo-asset'; const image = Asset.fromModule( require('./assets/images/demo.png') ); await image.downloadAsync();
这种方式适合:
-
游戏类应用
-
大量本地图片
-
离线应用
可以确保资源提前加载完成。
九、检查构建方式是否正确
Expo 项目目前主要有两种 Android 构建方式:
1. EAS Build
推荐方式:
Basheas build -p android
适用于正式发布。
2. 本地构建
例如:
Bashnpx expo run:android
适合开发调试。
如果开发环境正常,本地运行正常,但 EAS APK 异常,需要重点检查:
-
EAS缓存
-
构建配置
-
环境变量
-
资源路径
十、重新安装APK测试
Android 系统可能保留旧版本资源。
测试时不要直接覆盖安装,可以:
-
卸载旧 APK
-
清理应用数据
-
安装最新 APK
执行:
Bashadb uninstall com.example.app
然后:
Bashadb install app-release.apk
避免旧缓存影响测试结果。
十一、常见问题快速排查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 开发环境显示,APK不显示 | 图片未打包 | 检查require引用 |
| 新增图片无效 | Metro缓存 | 执行expo start -c |
| 部分手机不显示 | 文件大小写问题 | 统一小写命名 |
| 图片替换后仍旧显示旧图 | 缓存问题 | 修改文件名 |
| 动态图片加载失败 | 路径无法解析 | 使用图片映射 |
| EAS构建缺少资源 | 构建缓存 | 清理EAS缓存 |
十二、推荐的Expo图片管理规范
为了避免后续构建出现资源问题,可以采用以下规范:
1. 图片统一目录
例如:
assets/ └── images/ ├── logo.png ├── banner.png └── avatar.png
2. 使用静态require
推荐:
JavaScriptsource={require('./assets/images/logo.png')} />
避免:
JavaScriptsource={{uri:'logo.png'}} />
3. 文件名全部小写
推荐:
home_icon.png user_avatar.png
避免:
HomeIcon.PNG UserAvatar.PNG
4. 构建前清理缓存
正式打包前:
Bashnpx expo start -c eas build --clear-cache
Expo项目构建APK后新图片无法展示,核心原因通常集中在资源未被打包、路径引用错误、缓存未刷新以及Android大小写敏感等方面。按照“检查引用方式 → 清理缓存 → 验证构建资源 → 排查缓存”的顺序处理,大多数图片显示异常都可以快速解决。