Flutter For OpenHarmony:网络请求接入与数据清单列表构建(Day 3)
在 OpenHarmony 网络环境下,dio 默认请求头过于“简洁”,缺少 User-Agent / Accept 等信息,触发了服务端或中间网络节点的拦截策略。在 UI 层,数据清单采用 Flutter 中常用的 ListView.builder 构建,相比 UI 或工程创建,这一步更贴近真实业务场景,也更容易暴露跨平台差异问题。为开源鸿蒙跨平台工程集成网络请求能力,并在真机上完成数据清单列表
一. 任务背景与目标
在前两天完成了 Flutter for OpenHarmony 工程环境搭建 以及 Hello World 真机跑通 之后,Day 3 的核心任务开始转向应用能力本身:
为开源鸿蒙跨平台工程集成网络请求能力,并在真机上完成数据清单列表的完整验证。
相比 UI 或工程创建,这一步更贴近真实业务场景,也更容易暴露跨平台差异问题。
本次 Day 3 的目标可以概括为四点:
- 在 Flutter for OpenHarmony 工程中完成网络请求能力接入
- 正确配置 OpenHarmony 网络访问权限
- 基于网络数据完成 清单列表展示
- 在 OpenHarmony 真机 上稳定运行并验证结果
所使用的三方库为 dio(社区主流,功能完整)
二、Flutter 网络请求页面设计
1. 页面功能设计
为了避免“纯 UI 流程性内容”,页面功能刻意保持简洁(其实是我也不会 UI 和前端 ),但逻辑完整:
- 页面加载后自动发起网络请求
- 请求中展示 Loading 状态
- 请求成功展示列表
- 请求失败展示错误信息,并支持重试
- 支持下拉刷新
网络接口选用公开测试 API
https://jsonplaceholder.typicode.com/posts
2. 核心状态设计(Dart)
页面内部维护三类状态:
bool loading;
String? error;
List<dynamic> posts;
对应三种 UI 场景:
- loading:CircularProgressIndicator
- error:错误提示 + Retry
- success:ListView 渲染数据
三、OpenHarmony 网络权限配置
在 OpenHarmony 平台,网络访问必须显式声明权限。
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
不过我的 hello world 项目中已经显示声明该段内容了;二次确认了下。
四、实践过程
1. Dio 请求返回 403
在完成上述配置后,应用可以成功启动,但在 OpenHarmony 真机 上首次运行时,出现了如下错误界面:
核心内容应该是 Request failed DioException [bad response]: status code of 403
2. 问题分析
依次定位
- ❌ 网络未连接(设备网络正常)
- ❌ OpenHarmony 权限未声明(已配置 INTERNET)
- ❌ URL 错误(接口可在浏览器访问)
根本原因 - 请求头缺失
在 OpenHarmony 网络环境下,dio 默认请求头过于“简洁”,缺少 User-Agent / Accept 等信息,触发了服务端或中间网络节点的拦截策略。
3. 解决方法
在 Dio 的 BaseOptions 中显式指定请求头:
final Dio dio = Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
headers: {
'User-Agent': 'Mozilla/5.0 (Flutter; OpenHarmony)',
'Accept': 'application/json',
},
),
);
4. 成功运行
最终也是成功返回了数据,接口返回的是一个 JSON 数组,数组中的每一项表示一条“Post”数据,典型结构如下:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit suscipit recusandae consequuntur expedita et cum..."
}
dio 会将响应内容解析为 Dart 对象并保存为 posts 列表:
final resp = await dio.get(url);
final data = resp.data;
if (data is List) {
posts = data;
}
在 UI 层,数据清单采用 Flutter 中常用的 ListView.builder 构建,
在每一个列表项中:
- title 作为主标题展示
- id / userId 作为辅助信息
- body 作为内容摘要,限制最大行数,避免 UI 冗余

后续将尝试增加 dio 的拦截功能;以及对 UI 等进行补充完善。
欢迎加入开源鸿蒙跨平台社区
https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)