Flutter应用中OpenAI变量未初始化问题排查与修复求助
问题分析与修复方案
核心错误点
- 状态管理缺失:使用全局变量
response存储AI响应,但StatelessWidget无法监听普通变量的变化,即使请求成功UI也不会自动更新;同时在build方法中直接调用异步函数sendAI,会导致每次UI重建都重复发起请求。 - 初始化时机与方式问题:全局初始化
openAI可能因密钥无效、网络问题或包初始化逻辑导致实例未正确创建;且全局变量的方式不利于资源管理,容易引发内存泄漏。 - 空安全处理不足:
sendAI中使用ai?.onCompletion,如果openAI未初始化成功(为null),请求会静默失败,无法定位问题。
修复步骤与代码修改
1. 将弹窗改为StatefulWidget
通过状态类管理AI实例和响应内容,确保状态变化能触发UI更新。
2. 正确初始化与销毁AI实例
在initState中初始化OpenAI,在dispose中关闭资源,避免内存泄漏。
3. 优化请求触发时机
在UI构建完成后发起请求,避免重复调用,同时确保ViewModel数据已加载。
4. 增加异常处理
捕获请求过程中的错误,便于排查问题。
修改后的完整弹窗代码:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:todo_app/view_models/app_view_model.dart'; import '../../models/task_model.dart'; import 'package:chat_gpt_sdk/chat_gpt_sdk.dart'; class PrintTaskBottomSheetView extends StatefulWidget { const PrintTaskBottomSheetView({super.key}); @override State<PrintTaskBottomSheetView> createState() => _PrintTaskBottomSheetViewState(); } class _PrintTaskBottomSheetViewState extends State<PrintTaskBottomSheetView> { late OpenAI? _openAI; String _response = "No response?"; @override void initState() { super.initState(); // 替换为你的真实OpenAI API密钥 _openAI = OpenAI.instance.build( token: 'YOUR_REAL_OPENAI_API_KEY', baseOption: HttpSetup(receiveTimeout: const Duration(seconds: 60)), ); // 确保UI构建完成后再发起请求 WidgetsBinding.instance.addPostFrameCallback((_) { _sendAIRequest(); }); } @override void dispose() { _openAI?.close(); // 释放资源 super.dispose(); } void _sendAIRequest() async { final viewModel = Provider.of<AppViewModel>(context, listen: false); final taskText = viewModel.returnTasks(viewModel.tasks); if (taskText.isEmpty || _openAI == null) { setState(() { _response = "任务内容为空或AI实例初始化失败"; }); return; } try { final completionResponse = await _openAI!.onCompletion( request: CompleteText( prompt: taskText, model: TextDavinci3Model(), maxTokens: 200, // 根据需求调整返回文本长度 ), ); if (completionResponse != null && completionResponse.choices.isNotEmpty) { setState(() { _response = completionResponse.choices.last.text.trim(); }); } } catch (e) { setState(() { _response = "请求失败: ${e.toString()}"; }); } } @override Widget build(BuildContext context) { return Consumer<AppViewModel>( builder: (context, viewModel, child) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text( 'Printed Tasks', style: TextStyle(fontSize: 23, fontWeight: FontWeight.bold), ), const SizedBox(height: 20), Text(viewModel.returnTasks(viewModel.tasks)), const SizedBox(height: 20), Text(_response), ], ), ); }, ); } }
额外注意事项
- 必须将
YOUR_REAL_OPENAI_API_KEY替换为有效的OpenAI API密钥,否则_openAI会初始化失败。 - 若使用GPT-3.5-turbo或GPT-4模型,需改用
onChatCompletion接口,示例如下:
final chatRequest = ChatCompleteText( messages: [ {"role": "user", "content": taskText}, ], model: GptTurboModel(), ); final chatResponse = await _openAI!.onChatCompletion(request: chatRequest); if (chatResponse != null && chatResponse.choices.isNotEmpty) { setState(() { _response = chatResponse.choices.last.message?.content?.trim() ?? "无有效响应"; }); }
- 检查
chat_gpt_sdk包版本,确保与OpenAI当前API兼容。
内容的提问来源于stack exchange,提问作者PencilKnot
相关产品推荐
相关产品推荐

