Flutter中索引2之后图片加载失败,硬编码路径却正常
Flutter图片加载异常排查与解决
问题现象
- 从应用目录读取图片时,索引2之后的图片无法加载,路径看似正确,但硬编码相同路径却能正常显示
- 偶尔触发
libflutter.so栈溢出,非每次必现 - 抛出核心异常:
Cannot open file, path = ' /data/user/0/com.example.healamic/app_flutter/image_picker2935344680116023215.jpg' (OS Error: No such file or directory, errno = 2)
核心原因分析
- 路径字符串含前置空格:异常日志中的路径开头存在空格,而硬编码的路径无空格——这是导致文件找不到的直接原因,Hive存储的
item.paths字段中可能被意外添加了多余空格 - 序列化/反序列化逻辑疏漏:
LocalDocumentAdapter在处理paths字段时,未对字符串做清理,导致存储或读取时引入无效空格 - 批量图片加载资源竞争:大量图片同时加载可能引发内存资源冲突,是偶尔出现栈溢出的诱因
解决方案
1. 即时清理路径空格
在使用路径前调用trim()去除首尾无效空格:
for (final element in item.paths) Image.file(File(element.trim())),
2. 修复Hive序列化逻辑
确保LocalDocumentAdapter在读写paths字段时自动清理空格:
class LocalDocumentAdapter extends TypeAdapter<LocalDocument> { @override final int typeId = 0; @override LocalDocument read(BinaryReader reader) { final numOfFields = reader.readByte(); final fields = <int, dynamic>{ for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), }; // 读取时清理路径空格 final paths = (fields[0] as List<String>).map((p) => p.trim()).toList(); return LocalDocument(paths: paths); } @override void write(BinaryWriter writer, LocalDocument obj) { writer ..writeByte(1) ..writeByte(0) // 写入前清理路径空格,避免脏数据存储 ..write(obj.paths.map((p) => p.trim()).toList()); } }
3. 优化图片加载避免栈溢出
- 给图片添加
fit属性控制内存占用:
Image.file( File(element.trim()), fit: BoxFit.cover, width: double.infinity, )
- 增加文件存在性校验,提前拦截无效路径:
for (final element in item.paths) { final path = element.trim(); final file = File(path); if (await file.exists()) { Image.file(file); } else { // 显示占位图或错误提示 Text('文件不存在: $path'); } }
修正后的页面代码
ListView.builder( itemCount: ExtraUtilities.localDocuments.length, itemBuilder: (_, index) { final LocalDocument item = ExtraUtilities.localDocuments.getAt(index); return Column( children: [ for (final element in item.paths) FutureBuilder<bool>( future: File(element.trim()).exists(), builder: (context, snapshot) { if (snapshot.data == true) { return Image.file( File(element.trim()), fit: BoxFit.cover, width: double.infinity, ); } else { return const SizedBox( height: 100, child: Center(child: Text('图片加载失败')), ); } }, ), // 硬编码对比用 Image.file(File( '/data/user/0/com.example.healamic/app_flutter/image_picker2935344680116023215.jpg')) ], ); }, )
内容的提问来源于stack exchange,提问作者Suj
相关产品推荐
相关产品推荐

