Flutter for OpenHarmony:dio 网络请求库鸿蒙化适配与实战指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
摘要
本文将基于 dio 库,完整演示 Flutter for OpenHarmony 环境下网络请求能力的鸿蒙化适配方案,从依赖配置、权限声明到数据列表实战,提供可直接运行的完整代码,并验证其在鸿蒙设备上的实际运行效果,帮助开发者快速实现跨平台网络请求功能。
一、技术背景与方案选型
在跨平台开发中,网络请求是应用与后端交互的核心能力。Flutter 生态中主流的网络请求方案包括:
dio:生态最成熟的请求库,支持拦截器、FormData、Cookie 管理,适配性强
http:官方轻量级库,无冗余依赖,适合简单场景
chopper:基于注解生成请求代码,便于大型项目维护
本次实战选择 dio 作为适配方案,重点解决其在 OpenHarmony 平台的兼容性、权限适配与运行稳定性问题。
二、环境与前置配置
2.1 项目依赖配置
在项目根目录 pubspec.yaml 中添加 dio 依赖,选择与 OpenHarmony 兼容的稳定版本:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.7.0

执行 flutter pub get 拉取依赖,确保所有依赖无版本冲突。
2.2 鸿蒙网络权限声明
OpenHarmony 应用必须在 module.json5 中声明网络权限,否则会出现请求失败问题:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET",
        "reason": "$string:permission_internet_reason",
        "usedScene": {
          "abilities": ["./EntryAbility"],
          "when": "inuse"
        }
      }
    ]
  }
}

同时在 string.json 中添加权限说明文本:

{
  "string": [
    {
      "name": "permission_internet_reason",
      "value": "应用需要网络权限获取数据"
    }
  ]
}

三、完整代码实现
3.1 数据模型定义

// lib/model.dart
class DataItem {
  final int id;
  final String title;
  final String body;

  DataItem({
    required this.id,
    required this.title,
    required this.body,
  });

  factory DataItem.fromJson(Map<String, dynamic> json) {
    return DataItem(
      id: json['id'] ?? 0,
      title: json['title'] ?? '无标题',
      body: json['body'] ?? '无描述',
    );
  }
}

3.2 dio 请求服务封装

// lib/api_service.dart
import 'package:dio/dio.dart';
import 'model.dart';

class ApiService {
  final Dio _dio = Dio();

  ApiService() {
    // 基础配置,适配鸿蒙跨平台请求
    _dio.options.baseUrl = "https://jsonplaceholder.typicode.com";
    _dio.options.connectTimeout = const Duration(seconds: 10);
    _dio.options.receiveTimeout = const Duration(seconds: 10);
    // 日志拦截器,方便调试请求过程
    _dio.interceptors.add(LogInterceptor(
      request: true,
      responseBody: true,
      error: true,
    ));
  }

  // 获取数据列表
  Future<List<DataItem>> fetchDataList() async {
    try {
      final response = await _dio.get("/posts");
      if (response.statusCode == 200) {
        List<dynamic> dataList = response.data;
        return dataList.map((json) => DataItem.fromJson(json)).toList();
      } else {
        throw Exception("请求失败,状态码:${response.statusCode}");
      }
    } on DioException catch (e) {
      throw Exception("网络错误:${e.message}");
    }
  }
}

3.3 主页面实现与数据渲染

// lib/main.dart
import 'package:flutter/material.dart';
import 'api_service.dart';
import 'model.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '鸿蒙网络请求实战',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const DataListPage(),
    );
  }
}

class DataListPage extends StatefulWidget {
  const DataListPage({super.key});

  @override
  State<DataListPage> createState() => _DataListPageState();
}

class _DataListPageState extends State<DataListPage> {
  final ApiService _apiService = ApiService();
  late Future<List<DataItem>> _dataFuture;

  @override
  void initState() {
    super.initState();
    _dataFuture = _apiService.fetchDataList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("数据清单列表")),
      body: FutureBuilder<List<DataItem>>(
        future: _dataFuture,
        builder: (context, snapshot) {
          // 加载中状态
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          // 错误状态
          if (snapshot.hasError) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text("加载失败:${snapshot.error}"),
                  const SizedBox(height: 16),
                  ElevatedButton(
                    onPressed: () {
                      setState(() {
                        _dataFuture = _apiService.fetchDataList();
                      });
                    },
                    child: const Text("重试"),
                  ),
                ],
              ),
            );
          }
          // 数据加载成功
          if (snapshot.hasData) {
            final dataList = snapshot.data!;
            return ListView.builder(
              itemCount: dataList.length,
              itemBuilder: (context, index) {
                final item = dataList[index];
                return ListTile(
                  title: Text(item.title),
                  subtitle: Text(item.body),
                  leading: CircleAvatar(child: Text(item.id.toString())),
                );
              },
            );
          }
          // 空状态
          return const Center(child: Text("暂无数据"));
        },
      ),
    );
  }
}

四、设备运行验证
4.1 编译与安装
连接 OpenHarmony 模拟器或真机设备
在 DevEco Studio 中点击「运行」按钮,编译并安装应用
应用启动后,自动执行网络请求并渲染数据列表
4.2 运行效果说明
加载中:页面显示圆形进度条,提示用户数据正在请求
加载成功:以列表形式展示 API 返回的所有数据项,包含 ID、标题和详情
加载失败:显示错误信息与重试按钮,用户可点击重新发起请求
五、鸿蒙化适配关键点与避坑指南
5.1 关键适配要点
版本兼容性:优先选择与 OpenHarmony SDK 兼容的 dio 稳定版本,避免使用过高版本导致兼容性问题
权限配置:必须声明 ohos.permission.INTERNET 权限,否则网络请求会被系统拦截
跨平台稳定性:使用日志拦截器排查请求问题,避免使用平台特定 API
API 选择:优先使用 HTTPS 接口,避免明文 HTTP 请求被鸿蒙安全策略限制
5.2 常见问题排查
表格
六、总结与扩展
本文完整演示了 Flutter for OpenHarmony 环境下 dio 网络请求库的适配与实战,从依赖配置、权限声明到数据列表渲染,提供了可直接运行的完整方案。开发者可基于此方案,进一步扩展请求拦截、错误重试、缓存管理等功能,适配更复杂的业务场景。
后续还可结合 dio 的拦截器实现统一请求头、响应处理,或配合 flutter_hooks 优化状态管理,提升跨平台网络请求模块的健壮性与可维护性。
运行实例
运行实例

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐