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

Flutter应用中OpenAI变量未初始化问题排查与修复求助

问题分析与修复方案

核心错误点

  1. 状态管理缺失:使用全局变量response存储AI响应,但StatelessWidget无法监听普通变量的变化,即使请求成功UI也不会自动更新;同时在build方法中直接调用异步函数sendAI,会导致每次UI重建都重复发起请求。
  2. 初始化时机与方式问题:全局初始化openAI可能因密钥无效、网络问题或包初始化逻辑导致实例未正确创建;且全局变量的方式不利于资源管理,容易引发内存泄漏。
  3. 空安全处理不足: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:14:52