Flutter使用sqflite存储API数据遇_TypeError错误的解决咨询
问题分析与修复方案
核心错误根源
- 模型类不匹配:你照搬了教程里的
Planets类处理Photos数据,字段结构完全不对应,直接导致类型转换失败; - JSON解析不规范:未将API返回的原始JSON数组转换为对应模型对象的
List,盲目改成无类型List后,又引发了空值类型异常; - 数据库操作类型不一致:无类型
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
相关产品推荐
相关产品推荐

