如何在 Dart 中使用 json_annotation 将 Uint8List 序列化为 json?

Posted

技术标签:

【中文标题】如何在 Dart 中使用 json_annotation 将 Uint8List 序列化为 json?【英文标题】:How to serialize Uint8List to json with json_annotation in Dart? 【发布时间】:2020-12-22 05:49:51 【问题描述】:

我创建了一个包含Uint8List 成员的简单类:

import "package:json_annotation/json_annotation.dart";
part "open***.g.dart";

@JsonSerializable()
class Open*** extends *** 
  Open***(Uint8List profile) 
    this.profile = profile;
  
  /...
  Uint8List profile = null;

但是,当在其上运行构建运行程序以生成 json 序列化程序时,我得到:

Could not generate `fromJson` code for `profile`.
None of the provided `TypeHelper` instances support the defined type.
package:my_app/folder/open***.dart:19:13
   ╷
19 │   Uint8List profile = null;
   │             ^^^^^^^

有没有办法为这种类型编写我自己的序列化程序?或者有没有更简单的方法? 我不想在 json 文件上有一个字符串,我想有实际的字节。这是一个小文件,因此在 json 中存储为字节数组是有意义的。

【问题讨论】:

【参考方案1】:

为 Uint8List 添加自定义 JSON 转换器

import 'dart:typed_data';
import 'package:json_annotation/json_annotation.dart';

class Uint8ListConverter implements JsonConverter<Uint8List, List<int>> 
  const Uint8ListConverter();

  @override
  Uint8List fromJson(List<int> json) 
    if (json == null) 
      return null;
    

    return Uint8List.fromList(json);
  

  @override
  List<int> toJson(Uint8List object) 
    if (object == null) 
      return null;
    

    return object.toList();
  

在 Uint8List 属性上使用 Uint8ListConverter。 在你的情况下:

import 'package:json_annotation/json_annotation.dart';
import 'dart:typed_data';
import 'package:.../uint8_list_converter.dart';

part 'open_***.g.dart';

@JsonSerializable(explicitToJson: true)
class Open*** 
  Open***(this.profile);

  @Uint8ListConverter()
  Uint8List profile = null;

  factory Open***.fromJson(Map<String, dynamic> json) =>
      _$Open***FromJson(json);

  Map<String, dynamic> toJson() => _$Open***ToJson(this);

在根项目路径下,从终端运行生成open_***.g.dart部分文件: flutter packages pub run build_runner build --delete-conflicting-outputs

【讨论】:

我在每个返回 null 行上都收到此代码的两个错误:“无法从方法 'fromJson' 返回类型为 'Null' 的值,因为它的返回类型为 ' Uint8List'”和“无法从方法'toJson'返回'Null'类型的值,因为它的返回类型为'List'”。【参考方案2】:

在您的Open*** 序列化方法中,将Uint8List 转换为List&lt;int&gt;。根据您的实现,它可能类似于:

class Open*** 
  factory Open***.fromJson(dynamic map) 
    return Open***(
        ...
        profile: Uint8List.fromList(map['profile'] ?? []),
    );
  

  toJson() 
    return 
      ...
      'profile': profile as List<int>,
    ;
  

【讨论】:

以上是关于如何在 Dart 中使用 json_annotation 将 Uint8List 序列化为 json?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dart 中使用类型别名/类型定义(也是非函数)?

如何在单元测试中访问 Dart 类

如何使用 dart 在 MultiPartRequest 中添加列表?

如何在 Dart 中获得车辆的速度 [重复]

查询时如何在 Flutter (Dart) 中使用变量 Cloud Firestore

如何使用 Dart 构建枚举? [复制]