云计算百科
云计算领域专业知识百科平台

Flutter for OpenHarmony (三)网络请求OH模拟器到服务器

题记

上一篇,我们简单实现了一个列表与表单,接下来我们考虑将表单的数据存储到后端,这个时候就涉及到网络请求。 本篇主要任务是打通虚拟机到宿主机器之间的网络连接,本地启动一个服务,然后从鸿蒙的虚拟机请求本地服务,获取数据。 上次的篇幅有点长导致省略的很多的地方,这次步子迈小点(不扯蛋咱们开始)。 世界,开始!

本次任务

  • 配置鸿蒙模拟器连接外网
  • 配置本地node服务
  • 使用flutter 开发一个 请求本地接口的demo
  • app请求,并获取数据展示列表页。
  • 配置本地接口

    本地配置的网络环境,就选择自己最熟悉的语言就行。这里我选择了 nodejs fastify。 假定你已经配置好了nodejs的环境了(如果没有的话 还是推荐asdf ,我们第一篇已经提到了,如果你选择用它的话,这次正好你熟悉哈哈),我们这里就不讲nodejs环境配置了直接开始。

    安装Fastify

    mkdir fastify-s && cd fastify-s
    yarn init -y
    # 一路enter
    yarn add fastify

    安装完依赖,我们简单写一个服务,返回一个数组。

    // main.js
    import Fastify from 'fastify'
    const fastify = Fastify({
    logger: true
    })

    // Declare a route
    fastify.get('/', async function handler(request, reply) {
    return [{ hello: 'world' }]
    })
    // 10.0.2.2:3000

    // Run the server!
    try {
    await fastify.listen({ port: 3000 })
    } catch (err) {
    fastify.log.error(err)
    process.exit(1)
    }

    都是很简单的东西,这里我们启动并验证一下服务看看有没有问题。 在这里插入图片描述 这里也是提一下我的node版本是24.3.0,不用其它的包就支持热更新。 看图里 我们的服务也是正常的启动了。接下来我们验证一下请求看看是否正常。 ps: 这里还是需要提一下 在这里插入图片描述 如果出现这样的提示就是你忘记在package.json中设置module类型了,还有低版本的的node 并不能像我一样丝滑的直接启动esm代码哦。 在这里插入图片描述 OK!看来这里服务已经起来了。接下来我们就开始在flutter来获取hello world。

    在harmony虚拟机中请求接口

    安装请求库

    这里直接安装比较火的dio作为默认的请求库,Dio也是目前 Flutter 开发者首选的 HTTP 请求库,它的地位相当于前端开发中的 Axios。 在这里插入图片描述 这里还是跟之前一样,为了方便理解观看,我们新建一个页面。 在这里插入图片描述 这里我们的思路是,在请求的时候添加一个loading,获取完成数据进行渲染,没有数据就展示空。为了方便调试,另外添加一个icon按钮,点击之后就进行更新数据。

    import 'package:flutter/material.dart';
    import 'package:dio/dio.dart';

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


    _InternetState createState() => _InternetState();
    }

    class _InternetState extends State<Internet> {
    final dio = Dio();

    // 状态变量
    List<dynamic> _data = [];
    bool _isLoading = true; // 是否正在加载
    String? _errorMessage; // 错误信息


    void initState() {
    super.initState();
    // 只有在初始化时请求一次,或者由用户手动触发刷新
    _fetchData();
    }

    // 获取数据函数
    Future<void> _fetchData() async {
    try {
    setState(() {
    _isLoading = true;
    _errorMessage = null; // 清除之前的错误
    });

    // 10.0.2.2 是 Android 模拟器访问电脑本地的地址
    final response = await dio.get('http://10.0.2.2:3000/');

    setState(() {
    // 假设返回的是一个 List,如果不是,需要根据具体 JSON 结构解析
    _data = response.data as List<dynamic>;
    _isLoading = false;
    });
    } on DioException catch (e) {
    setState(() {
    _isLoading = false;
    _errorMessage = "网络请求失败: ${e.message}";
    });
    } catch (e) {
    setState(() {
    _isLoading = false;
    _errorMessage = "发生未知错误: $e";
    });
    }
    }


    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: const Text('Internet Data'),
    actions: [
    IconButton(onPressed: _fetchData, icon: const Icon(Icons.refresh)),
    ],
    ),
    body: _buildBody(), // 抽离主体内容判断
    );
    }

    // 逻辑判断渲染主体内容
    Widget _buildBody() {
    // 1. 加载中状态
    if (_isLoading) {
    return const Center(child: CircularProgressIndicator());
    }

    // 2. 错误状态
    if (_errorMessage != null) {
    return Center(
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    const Icon(Icons.error_outline, size: 48, color: Colors.red),
    const SizedBox(height: 16),
    Text(_errorMessage!),
    ElevatedButton(onPressed: _fetchData, child: const Text('重试')),
    ],
    ),
    );
    }

    // 3. 数据为空状态
    if (_data.isEmpty) {
    return const Center(
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    Icon(Icons.inbox, size: 48, color: Colors.grey),
    SizedBox(height: 16),
    Text('暂无数据'),
    ],
    ),
    );
    }

    // 4. 正常数据渲染
    return ListView.separated(
    padding: const EdgeInsets.all(8),
    itemCount: _data.length,
    itemBuilder: (context, index) {
    final item = _data[index];
    return ListTile(
    title: Text(item.toString()), // 根据你实际 JSON 的字段来,比如 item['name']
    subtitle: Text('ID: $index'),
    leading: const Icon(Icons.cloud_queue),
    );
    },
    separatorBuilder: (context, index) => const Divider(),
    );
    }
    }

    写完之后在路由配置中添加一下。

    final List<ListPage> RouteList = [
    ListPage(
    path: '/home',
    title: '计数器',
    icon: Icons.home,
    builder: (context) => const MyHomePage(title: '计数器'),
    ),
    ListPage(
    path: '/user_list',
    title: '用户管理',
    icon: Icons.person,
    builder: (context) => const UserListPage(),
    ),
    ListPage(
    path: '/internet',
    title: '网络请求',
    icon: Icons.http,
    builder: (context) => const Internet(),
    ),
    ];

    更新一下页面我门看看效果 在这里插入图片描述 点击进入网络请求页面,进入页面的时候会立即进行请求,这里我添加了一debug断点,我们看一下效果如愿以偿的获取到了 hello world 在这里插入图片描述 在这里插入图片描述 我们在后端新增一条数据,再次进行请求。 在这里插入图片描述 示例地址,点击跳转到gitcode

    总结

    本次任务圆满的完成 网络请求链路已打通,Flutter → OH模拟器 → 宿主机服务 的基本闭环验证通过。 项目源码已上传至:maolin319/harmony_sqllite_floor_demo(gitcode)。 主要是在鸿蒙文档中查到 ,在本地计算机上建立网络服务端,模拟器可以通过10.0.2.2:访问本地计算机服务端,其中10.0.2.2为模拟器的默认网关。,所以访问宿主机直接使用 10.0.2.2:3000。没毛病的老铁。 Flutter 在 OpenHarmony 上的网络子系统可行性已初步确认,无重大阻塞。

    欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Flutter for OpenHarmony (三)网络请求OH模拟器到服务器
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!