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

Flutter使用sqflite存储API数据遇_TypeError错误的解决咨询

问题分析与修复方案

核心错误根源

  1. 模型类不匹配:你照搬了教程里的Planets类处理Photos数据,字段结构完全不对应,直接导致类型转换失败;
  2. JSON解析不规范:未将API返回的原始JSON数组转换为对应模型对象的List,盲目改成无类型List后,又引发了空值类型异常;
  3. 数据库操作类型不一致:无类型List插入数据库时,因字段映射错误取不到有效值,导致null被赋值给int类型的数据库列。

1. 修正Model类(model.dart)

创建与Photos API结构匹配的Photo模型,确保JSON解析和数据库映射正确:

class Photo {
  final int albumId;
  final int id;
  final String title;
  final String url;
  final String thumbnailUrl;

  Photo({
    required this.albumId,
    required this.id,
    required this.title,
    required this.url,
    required this.thumbnailUrl,
  });

  // 从JSON转Photo对象
  factory Photo.fromJson(Map<String, dynamic> json) {
    return Photo(
      albumId: json['albumId'] as int,
      id: json['id'] as int,
      title: json['title'] as String,
      url: json['url'] as String,
      thumbnailUrl: json['thumbnailUrl'] as String,
    );
  }

  // 转Map用于数据库存储
  Map<String, dynamic> toMap() {
    return {
      'albumId': albumId,
      'id': id,
      'title': title,
      'url': url,
      'thumbnailUrl': thumbnailUrl,
    };
  }
}

如果担心API返回空值(该API无此情况),可给字段加默认值,比如json['albumId'] as int? ?? 0

2. 修正数据库操作类(db.dart)

确保表结构与Photo模型匹配,操作时严格对应类型:

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'model.dart';

class DatabaseHelper {
  static final DatabaseHelper _instance = DatabaseHelper._internal();
  factory DatabaseHelper() => _instance;
  DatabaseHelper._internal();

  static Database? _database;

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDatabase();
    return _database!;
  }

  Future<Database> _initDatabase() async {
    String path = join(await getDatabasesPath(), 'photos.db');
    return await openDatabase(
      path,
      version: 1,
      onCreate: (db, version) async {
        await db.execute('''
          CREATE TABLE photos(
            albumId INTEGER,
            id INTEGER PRIMARY KEY,
            title TEXT,
            url TEXT,
            thumbnailUrl TEXT
          )
        ''');
      },
    );
  }

  // 批量插入照片(比单条插入高效)
  Future<void> insertPhotos(List<Photo> photos) async {
    final db = await database;
    Batch batch = db.batch();
    for (var photo in photos) {
      batch.insert(
        'photos',
        photo.toMap(),
        conflictAlgorithm: ConflictAlgorithm.replace
      );
    }
    await batch.commit();
  }

  // 查询所有照片
  Future<List<Photo>> getPhotos() async {
    final db = await database;
    final List<Map<String, dynamic>> maps = await db.query('photos');
    return List.generate(maps.length, (i) {
      return Photo(
        albumId: maps[i]['albumId'] as int,
        id: maps[i]['id'] as int,
        title: maps[i]['title'] as String,
        url: maps[i]['url'] as String,
        thumbnailUrl: maps[i]['thumbnailUrl'] as String,
      );
    });
  }
}

3. 修正主逻辑文件(gg.dart)

规范API数据解析流程,先转成List<Photo>再插入数据库:

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'model.dart';
import 'db.dart';

Future<void> fetchAndSavePhotos() async {
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/photos'));
  
  if (response.statusCode == 200) {
    // 先转成原始JSON数组,再映射为Photo对象列表
    List<dynamic> jsonList = json.decode(response.body);
    List<Photo> photos = jsonList.map((json) => Photo.fromJson(json)).toList();
    
    // 插入数据库
    await DatabaseHelper().insertPhotos(photos);
    print('数据存储成功');
  } else {
    throw Exception('加载照片失败');
  }
}

内容的提问来源于stack exchange,提问作者Kvu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:35:36