Flutter中如何实现可跨dart文件调用的Future函数内部方法
问题根因
- 作用域问题:
insertToken方法是定义在tokenDb函数内部的局部方法,仅在tokenDb函数内部可访问,外部无法直接调用 - 类型错误:
tokenDb的返回值是Future类型,并非包含insertToken方法的实例对象,自然无法通过返回值调用内部方法 - 隐性错误:你创建表时定义
token字段为INTEGER类型,但Firebase返回的设备token是字符串类型,后续存储会报错
解决方案
推荐封装独立的数据库工具类,统一管理数据库初始化和CRUD操作,方便全局调用:
1. 编写数据库工具类
import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; // 确保你的Token类定义如下,包含toMap方法 class Token { final String token; Token({required this.token}); Map<String, dynamic> toMap() { return {'token': token}; } } class TokenDbManager { // 单例实例,全局复用 static final TokenDbManager _instance = TokenDbManager._internal(); factory TokenDbManager() => _instance; TokenDbManager._internal(); // 数据库实例缓存,避免重复初始化 static Database? _database; // 获取数据库实例 Future<Database> get database async { if (_database != null) return _database!; _database = await _initDb(); return _database!; } // 初始化数据库 Future<Database> _initDb() async { final dbPath = await getDatabasesPath(); final path = join(dbPath, 'token_list.db'); return await openDatabase( path, onCreate: (db, version) { // 注意把token字段类型改为TEXT适配字符串格式的token return db.execute( "CREATE TABLE tokens (token TEXT PRIMARY KEY)", ); }, version: 1, ); } // 对外暴露的插入token方法 Future<void> insertToken(Token token) async { final db = await database; await db.insert( 'tokens', token.toMap(), conflictAlgorithm: ConflictAlgorithm.replace, ); } // 后续需要查询、删除token等操作,都可以在这里新增对应方法 }
2. 调用逻辑修改
调整你initState中的调用代码即可正常执行插入:
@override void initState() { super.initState(); messaging = FirebaseMessaging.instance; messaging.getToken().then((value) async { if (value == null) return; tokenValue = value; Clipboard.setData(ClipboardData(text: tokenValue)); print(tokenValue); var user1 = Token(token: tokenValue); print("user1 token : $tokenValue"); // 直接调用工具类的插入方法 await TokenDbManager().insertToken(user1); print("token插入完成"); }); }
额外说明
如果你不想封装成类,也可以直接把insertToken方法移到tokenDb函数外部作为全局方法,调用时先await tokenDb()拿到数据库实例再执行插入操作即可。但封装成单例工具类是更规范的开发方式,能避免重复初始化数据库,也方便后续扩展其他数据库操作。
内容的提问来源于stack exchange,提问作者Kate Jo
相关产品推荐
相关产品推荐

