Flutter中Object Box存储URL图片后iconData为空的问题求助
Object Box存储图片数据后iconData变为null的排查解决
在Flutter中使用Object Box存储从URL下载的图片数据时,创建ServiceModel实例时iconData有有效字节长度,但调用putMany存储后查询返回的iconData却为null。相关代码与执行日志如下:
实体类与数据源代码
@Entity() class ServiceModel { @Id() int id = 0; @Unique() final String identifier; final String name; final String type; final String icon; // Keep the URL for reference final String language; final List<String> emails; final int mainContact; @Property(type: PropertyType.byte) Uint8List? iconData; @Property(type: PropertyType.intVector) final List<int> otherContacts; ServiceModel({ this.id = 0, required this.identifier, required this.name, required this.type, required this.icon, required this.emails, required this.mainContact, required this.otherContacts, required this.language, this.iconData, }); // Convert Service to ServiceModel with image download static Future<ServiceModel> fromService( Service service, String language) async { Uint8List? downloadedIconData; try { print("Downloading image from: ${service.icon}"); final response = await http.get(Uri.parse(service.icon)); print("Response status: ${response.statusCode}"); print("Response body length: ${response.bodyBytes.length}"); if (response.statusCode == 200) { downloadedIconData = response.bodyBytes; print("Downloaded image size: ${downloadedIconData.length} bytes"); } } catch (e) { print('Failed to download icon for ${service.identifier}: $e'); } final model = ServiceModel( identifier: service.identifier, name: service.name, type: service.type, icon: service.icon, emails: service.emails, mainContact: mainContact, otherContacts: otherContacts, language: language, iconData: downloadedIconData, ); print( "ServiceModel created with iconData length: ${model.iconData?.length}"); return model; } // Convert ServiceModel to Service Service toService() { return Service( identifier: identifier, name: name, type: type, icon: icon, emails: emails, mainContact: mainContact, otherContacts: otherContacts, iconData: iconData, ); } } class MesServiceLocalDataSource implements MesDataSource { final Store store; MesServiceLocalDataSource(this.store); @override Future<List<Service>> getAllServices(String lang) async { print("Getting services locally"); final box = store.box<ServiceModel>(); final services = box.query(ServiceModel_.language.equals(lang)).build().find(); print("Found ${services.length} services"); for (var service in services) { print( "Service ${service.identifier} iconData length: ${service.iconData?.length}"); } return services.map((model) => model.toService()).toList(); } Future<void> cacheServices(List<Service> services, String lang) async { final box = store.box<ServiceModel>(); // Delete existing services for this language final existingServices = box.query(ServiceModel_.language.equals(lang)).build().find(); box.removeMany(existingServices.map((e) => e.id).toList()); // Store new services with downloaded images final serviceModels = await Future.wait( services.map((service) => ServiceModel.fromService(service, lang))); print("Storing ${serviceModels.length} services"); print( "First service iconData length: ${serviceModels[0].iconData?.length}"); box.putMany(serviceModels); // Verify storage final storedServices = box.getAll(); print("Stored services count: ${storedServices.length}"); print( "First stored service iconData length: ${storedServices[0].iconData?.length}"); } }
执行日志
I/flutter (23274): Storing 18 services I/flutter (23274): First service iconData length: 4571 I/flutter (23274): Stored services count: 18 I/flutter (23274): First stored service iconData length: null
问题排查与解决
问题根源在于iconData字段的@Property注解类型错误:
- 当前使用的
PropertyType.byte仅对应单个字节(8位整数),无法存储Uint8List类型的字节数组。 - 正确的类型应为
PropertyType.byteVector,专门用于存储字节数组。
修改ServiceModel中的iconData字段注解:
@Property(type: PropertyType.byteVector) Uint8List? iconData;
修改完成后,必须重新生成Object Box的适配器代码,执行以下命令:
flutter pub run build_runner build
重新运行代码后,iconData即可被正确存储和读取。
内容的提问来源于stack exchange,提问作者Mervin Hemaraju
相关产品推荐
相关产品推荐

