You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:54:59