首页 > 解决方案 > HiveError(HiveError:无法写入,未知类型:Slug。您忘记注册适配器了吗?)

问题描述

我正在构建一个非常简单的应用程序来从流行的动漫网站流式传输动漫,但是我很难使用 Hive。

我正在尝试从动漫网站获取所有动漫,然后将其保存到 Hive 中的缓存。但是我遇到了问题,这阻碍了我的发展。我注册了一个适配器,但 Hive 告诉我我没有。

有谁知道如何解决它?

我的代码

lib/main.dart

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:twist_go/pages/nav_screen.dart';

void main() async {
  runApp(EasyLocalization(
    supportedLocales: [Locale('en', 'US')],
    path: 'lib/assets/translations',
    fallbackLocale: Locale('en', 'US'),
    child: TwistGO(),
  ));
}

class TwistGO extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Colors.blueGrey[800],
        scaffoldBackgroundColor: Colors.blueGrey[700],
      ),
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      home: NavScreen(),
    );
  }
}

模型/anime_all.dart

import 'dart:convert';

import 'package:hive/hive.dart';

part 'anime_all.g.dart';

List<AnimeAll> animeAllFromJson(String str) =>
    List<AnimeAll>.from(json.decode(str).map((x) => AnimeAll.fromJson(x)));

String animeAllToJson(List<AnimeAll> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

@HiveType(typeId: 0)
class AnimeAll extends HiveObject {
  @HiveField(0)
  final int id;

  @HiveField(1)
  final String title;

  @HiveField(2)
  final String altTitle;

  @HiveField(3)
  final int season;

  @HiveField(4)
  final int ongoing;

  @HiveField(5)
  final int hbId;

  @HiveField(6)
  final DateTime createdAt;

  @HiveField(7)
  final DateTime updatedAt;

  @HiveField(8)
  final int hidden;

  @HiveField(9)
  final int malId;

  @HiveField(10)
  final Slug slug;

  AnimeAll({
    this.id,
    this.title,
    this.altTitle,
    this.season,
    this.ongoing,
    this.hbId,
    this.createdAt,
    this.updatedAt,
    this.hidden,
    this.malId,
    this.slug,
  });

  factory AnimeAll.fromJson(Map<String, dynamic> json) => AnimeAll(
        id: json["id"],
        title: json["title"],
        altTitle: json["alt_title"] == null ? null : json["alt_title"],
        season: json["season"],
        ongoing: json["ongoing"],
        hbId: json["hb_id"] == null ? null : json["hb_id"],
        createdAt: DateTime.parse(json["created_at"]),
        updatedAt: DateTime.parse(json["updated_at"]),
        hidden: json["hidden"],
        malId: json["mal_id"] == null ? null : json["mal_id"],
        slug: Slug.fromJson(json["slug"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "title": title,
        "alt_title": altTitle == null ? null : altTitle,
        "season": season,
        "ongoing": ongoing,
        "hb_id": hbId == null ? null : hbId,
        "created_at": createdAt.toIso8601String(),
        "updated_at": updatedAt.toIso8601String(),
        "hidden": hidden,
        "mal_id": malId == null ? null : malId,
        "slug": slug.toJson(),
      };
}

class Slug {
  Slug({
    this.id,
    this.slug,
    this.animeId,
    this.createdAt,
    this.updatedAt,
  });

  int id;
  String slug;
  int animeId;
  DateTime createdAt;
  DateTime updatedAt;

  factory Slug.fromJson(Map<String, dynamic> json) => Slug(
        id: json["id"],
        slug: json["slug"],
        animeId: json["anime_id"],
        createdAt: DateTime.parse(json["created_at"]),
        updatedAt: DateTime.parse(json["updated_at"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "slug": slug,
        "anime_id": animeId,
        "created_at": createdAt.toIso8601String(),
        "updated_at": updatedAt.toIso8601String(),
      };
}

模型/anime_all.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'anime_all.dart';

// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************

class AnimeAllAdapter extends TypeAdapter<AnimeAll> {
  @override
  final int typeId = 0;

  @override
  AnimeAll read(BinaryReader reader) {
    final numOfFields = reader.readByte();
    final fields = <int, dynamic>{
      for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return AnimeAll(
      id: fields[0] as int,
      title: fields[1] as String,
      altTitle: fields[2] as String,
      season: fields[3] as int,
      ongoing: fields[4] as int,
      hbId: fields[5] as int,
      createdAt: fields[6] as DateTime,
      updatedAt: fields[7] as DateTime,
      hidden: fields[8] as int,
      malId: fields[9] as int,
      slug: fields[10] as Slug,
    );
  }

  @override
  void write(BinaryWriter writer, AnimeAll obj) {
    writer
      ..writeByte(11)
      ..writeByte(0)
      ..write(obj.id)
      ..writeByte(1)
      ..write(obj.title)
      ..writeByte(2)
      ..write(obj.altTitle)
      ..writeByte(3)
      ..write(obj.season)
      ..writeByte(4)
      ..write(obj.ongoing)
      ..writeByte(5)
      ..write(obj.hbId)
      ..writeByte(6)
      ..write(obj.createdAt)
      ..writeByte(7)
      ..write(obj.updatedAt)
      ..writeByte(8)
      ..write(obj.hidden)
      ..writeByte(9)
      ..write(obj.malId)
      ..writeByte(10)
      ..write(obj.slug);
  }

  @override
  int get hashCode => typeId.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is AnimeAllAdapter &&
          runtimeType == other.runtimeType &&
          typeId == other.typeId;
}

服务/网络/anime_twist.dart

import 'package:http/http.dart' as http;
import 'package:twist_go/models/anime_all.dart';
import 'package:twist_go/.env.dart';
import 'package:twist_go/models/anime_single.dart';
import 'package:twist_go/models/anime_sources.dart';

class AnimeTwistApiService {
  static const String _baseUrl = 'https://twist.moe/api/anime/';
  var _headers = {'x-access-token': EnvironmentVariables.token};

  Future<List<AnimeAll>> getAllAnime() async {
    final http.Response response = await http.get(
      _baseUrl,
      headers: _headers,
    );

    return animeAllFromJson(response.body);
  }

  Future<AnimeSingle> getSingleAnime(String slug) async {
    final http.Response response = await http.get(
      _baseUrl + slug,
      headers: _headers,
    );

    return animeSingleFromJson(response.body);
  }

  Future<List<AnimeSources>> getAnimeSources(String slug) async {
    final http.Response response = await http.get(
      _baseUrl + slug + '/sources',
      headers: _headers,
    );

    return animeSourcesFromJson(response.body);
  }
}

服务/db/anime_twist_cache.dart

import 'package:hive/hive.dart';
import 'package:twist_go/models/anime_all.dart';
import 'package:twist_go/services/net/anime_twist.dart';
import 'package:path_provider/path_provider.dart' as path_provider;

class AnimeTwistCacheService {
  Future<void> cacheAllAnime() async {
    final _appDocumentDir =
        await path_provider.getApplicationDocumentsDirectory();
    Hive.init(_appDocumentDir.path);
    Hive.registerAdapter<AnimeAll>(AnimeAllAdapter());

    Hive.openBox('all-anime');
    final AnimeTwistApiService _animeTwistApiService = AnimeTwistApiService();

    List<AnimeAll> allAnime = await _animeTwistApiService.getAllAnime();

    Hive.box('all-anime').add(allAnime);
  }
}

标签: flutterdart

解决方案


在您的适配器(models/anime_all.dart)中,您有slugtype字段,Slug因此您还必须创建一个适配器并将其注册到Slug该类。


推荐阅读