【开源鸿蒙跨平台开发先锋训练营】[Day 3] React Native for OpenHarmony 实战:网络请求集成与高健壮性列表构建

📅 核心任务

本日重点攻克 OpenHarmony 环境下的网络通信 难关。不再是简单的 UI 堆砌,而是打通 "端-云" 链路,使用 React Native 技术栈(Axios + FlatList)实现一个具备 加载状态、错误兜底、下拉刷新 的完整数据列表,并在鸿蒙真机/模拟器上验证运行。


🚀 一、 破局:鸿蒙网络权限的"隐形墙"

在 Android 开发中我们习惯了 AndroidManifest.xml,而在 OpenHarmony 中,权限管理有着更严格的声明式规范。很多初学者代码写得天衣无缝,请求却永远发不出去,往往就是倒在了这一步。

1.1 权限声明机制

OpenHarmony 的权限管理位于 entry/src/main/module.json5 中。不同于 Android 的粗放,鸿蒙对权限有着明确的等级划分。

  • 什么是 module.json5? 它是鸿蒙应用的核心配置文件,类似于 Android 的 AndroidManifest.xml 或 iOS 的 Info.plist。它定义了应用的标识、组件、权限等关键信息。
  • requestPermissions 字段:这是一个数组,用来告诉系统"我需要哪些特权"。没有在这里声明的权限,应用运行时一律无法获取。

关键配置

打开 harmony/entry/src/main/module.json5,在 module 节点下新增 requestPermissions

json5 复制代码
"module": {
  // ... 其他配置
  "requestPermissions": [
    {
      "name": "ohos.permission.INTERNET", // 权限名称:允许访问互联网
      "reason": "$string:dependency_reason", // 申请理由:需要在多语言资源文件中定义,如果不涉及上架,暂可随意填写
      "usedScene": {
        "abilities": [
          "EntryAbility" // 适用的 Ability 组件,通常是主入口
        ],
        "when": "inuse" // 授权时机:inuse 表示使用时授权
      }
    }
  ]
}

1.2 ⚠️ 技术避坑指南:HTTP 明文流量限制

问题现象 :使用 http:// 接口请求失败,但 https:// 正常。
深度解析 :OpenHarmony 默认策略与 Android 高版本类似,禁止明文 HTTP 流量。这是为了防止中间人攻击,保护用户数据安全。
解决方案

  1. 首选:服务端升级 HTTPS(最安全)。现在 Let's Encrypt 等机构提供免费证书,升级 HTTPS 是行业标准。
  2. 临时方案 :在 module.json5deviceConfig (API 9 以前) 或相关网络安全配置文件中允许明文流量(不推荐生产环境)。但在 RNOH 当前适配中,底层网络库通常遵循系统默认安全策略,建议直接使用 HTTPS 避免不必要的底层调试。

🛠️ 二、 核心技术栈选型:Axios on Harmony

虽然 RN 提供了 fetch,但在企业级开发中,Axios 依然是首选。

2.1 为什么选择 Axios?

在 RNOH 架构中,JavaScript 端的网络请求最终会通过 RN 的 Bridge/TurboModule 调用到鸿蒙系统的网络能力。Axios 基于 XMLHttpRequest 适配,而 RNOH 完整实现了这一 API。

  • 拦截器(Interceptors):就像是快递站的安检员。发货前(请求拦截器)可以统一贴上标签(如 Token),收货时(响应拦截器)可以统一拆箱验货(处理 401 登出、统一错误提示)。
  • 自动转换 :Axios 会自动将服务器返回的 JSON 字符串转成 JS 对象,少写一行 response.json()
  • 取消请求:页面关闭时,如果请求还没回来,可以取消它,防止组件已销毁但请求回调还在执行导致的内存泄漏。

2.2 封装实战

不要直接在组件里调用 axios.get。建立 src/utils/request.ts,这样如果以后要换网络库,只需要改这一个文件。

typescript 复制代码
import axios from 'axios';
import { Alert, Platform } from 'react-native';

const instance = axios.create({
  baseURL: 'https://api.example.com', // 替换为实际 API
  timeout: 10000, // 超时时间:10秒,网络不好时不会一直卡住
});

// 响应拦截器:统一错误处理
instance.interceptors.response.use(
  response => response.data, // 直接返回数据部分,过滤掉 header 等信息
  error => {
    // 针对鸿蒙平台的特定错误日志
    // Platform.OS === 'harmony' 是 RNOH 特有的判断,用于区分鸿蒙平台
    if (Platform.OS === 'harmony') {
      console.error('[RNOH] Network Error:', error);
    }
    return Promise.reject(error);
  }
);

export default instance;

📊 三、 构建高健壮性数据列表

在鸿蒙设备上渲染长列表,性能是关键。我们使用 FlatList 并结合 TypeScript 进行类型约束。FlatList 是 RN 的高性能列表组件,它只渲染屏幕上可见的元素,看不见的会回收,非常适合长列表。

3.1 列表渲染策略

  • 防抖动 :网络请求尽量放在 useEffect 中。useEffect 就像是组件的"生命周期钩子",空数组 [] 意味着只在组件挂载时执行一次,避免每次渲染都发请求造成死循环。
  • 空状态兜底(Empty State) :网络慢或无数据时,不能白屏,要给用户反馈。ListEmptyComponent 属性就是专门干这个的。
  • Key 优化keyExtractor 必须唯一。React 需要用 key 来识别哪些元素改变了。如果 key 不唯一,Diff 算法就会混乱,导致鸿蒙 ArkUI 渲染性能下降,甚至 UI 错乱。

3.2 完整代码实现 (ProductList.tsx)

tsx 复制代码
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList, ActivityIndicator, StyleSheet, RefreshControl } from 'react-native';
import request from '../utils/request';

// 定义数据结构接口,TS 的好处是写代码时就有提示
interface ItemData {
  id: string;
  title: string;
  desc: string;
}

const ProductList = () => {
  // useState: 管理组件内部状态
  const [data, setData] = useState<ItemData[]>([]); // 列表数据
  const [loading, setLoading] = useState(true); // 是否正在初次加载
  const [refreshing, setRefreshing] = useState(false); // 是否正在下拉刷新

  const fetchData = async () => {
    try {
      // 真实请求示例:
      // const res = await request.get('/products');
      // setData(res.list);
      
      // Mock 数据用于演示:模拟 1秒后返回数据
      setTimeout(() => {
        // Array.from 生成 20 条模拟数据
        setData(Array.from({ length: 20 }).map((_, i) => ({
            id: String(i),
            title: `鸿蒙跨端商品 ${i + 1}`,
            desc: 'React Native for OpenHarmony 运行验证'
        })));
        setLoading(false); // 停止 loading 转圈
        setRefreshing(false); // 停止下拉刷新转圈
      }, 1000);
    } catch (err) {
      console.error(err);
      setLoading(false);
      setRefreshing(false);
      // 实际项目中这里应该提示用户"网络错误"
    }
  };

  // 组件挂载完成后立即请求数据
  useEffect(() => {
    fetchData();
  }, []);

  // 下拉刷新触发的方法
  const onRefresh = () => {
    setRefreshing(true);
    fetchData();
  };

  // 首次加载时的 Loading 页面
  if (loading && !refreshing) {
    return <ActivityIndicator size="large" color="#0a59f7" style={styles.center} />;
  }

  return (
    <FlatList
      data={data}
      keyExtractor={(item) => item.id} // 告诉 RN 每一项的唯一 ID 是什么
      refreshControl={
        // 下拉刷新组件
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }
      renderItem={({ item }) => (
        // 每一行长什么样
        <View style={styles.item}>
          <Text style={styles.title}>{item.title}</Text>
          <Text style={styles.desc}>{item.desc}</Text>
        </View>
      )}
      ListEmptyComponent={
        // 没数据时显示什么
        <Text style={styles.emptyText}>暂无数据,请检查网络连接</Text>
      }
    />
  );
};

const styles = StyleSheet.create({
  center: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  item: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#eee' },
  title: { fontSize: 18, fontWeight: 'bold', color: '#333' },
  desc: { marginTop: 8, color: '#666' },
  emptyText: { textAlign: 'center', marginTop: 50, color: '#999' }
});

export default ProductList;

🔍 四、 深度排查与验证 (Troubleshooting)

在将代码部署到 OpenHarmony 真机/模拟器时,可能会遇到以下问题:

4.1 编译报错:Could not find "libRNOHApp.so"

现象 :引入新库后,C++ 链接失败。
分析 :React Native for OpenHarmony 包含 C++ 代码(原生模块)。如果你更新了依赖,原来的构建缓存可能和新依赖不匹配。
解决

  1. 清理构建 :运行 cd harmony && ./hvigorw.bat clean。这相当于把房子拆了重新盖,清除所有旧的构建产物。
  2. 同步依赖 :确保 oh-package.json5 中的依赖已同步。
  3. 重新 Sync:在 DevEco Studio 中点击 "Sync Project with Gradle Files" (或者类似的 Sync 按钮)。

4.2 运行时:Network Error 但其他 App 正常

分析

  • 权限未生效 :检查 module.json5 修改后是否重新安装 了 HAP?鸿蒙的热重载(Hot Reload)通常只更新 JS 代码,不更新配置文件。修改了 module.json5 必须重新点击 Run 按钮进行全量安装。
  • 时间不对:检查设备时间是否准确。HTTPS 协议需要校验 SSL 证书的有效期,如果设备时间还在 1970 年,证书校验就会失败,导致请求被拒绝。

📝 五、 代码提交与 Git 规范

完成验证后,推送到 AtomGit。Git 是团队协作的基石,规范的提交记录能让队友一眼看懂你干了什么。

bash 复制代码
# 1. 检查状态:看看修改了哪些文件
git status

# 2. 添加变更:把所有修改放入暂存区
git add .

# 3. 提交代码 (遵循 Commit Message 规范)
# 格式: feat(模块): 描述
# feat 表示新功能,fix 表示修复 bug
git commit -m "feat(network): 集成Axios并实现商品列表页
- 配置 module.json5 网络权限
- 封装 Axios 请求工具类
- 实现 FlatList 下拉刷新与空状态处理"

# 4. 推送到远程 dev 分支
git push origin dev

🌟 总结

今天我们跨越了 RNOH 开发的一个重要里程碑:与外部世界通信 。虽然代码层面主要是 JS,但底层的权限配置、网络策略、以及在鸿蒙设备上的实际表现,都体现了跨平台开发的特殊性------既要懂前端的灵动,也要懂原生的规矩

欢迎加入开源鸿蒙跨平台社区:

https://openharmonycrossplatform.csdn.net

相关推荐
-大头.2 小时前
GIT教程系列(共3篇)-----第三篇:Git高级技巧与专业配置完全指南
大数据·git·elasticsearch
Coovally AI模型快速验证2 小时前
计算机视觉的 2026:从“堆算力”竞赛,到“省算力”智慧
人工智能·深度学习·算法·yolo·计算机视觉·无人机
roman_日积跬步-终至千里2 小时前
【Hadoop】HDFS Router-based Federation:解决 NameNode 扩展性问题的联邦方案
大数据·hadoop·hdfs
查拉图斯特拉面条2 小时前
Git推送完全指南:从首次推送到冲突解决
大数据·git·elasticsearch
王潇洒呀2 小时前
AI+测试工具《Testim》使用说明
人工智能·测试工具
软件测试君2 小时前
2025年10款王炸AI测试工具,你用过几款?
自动化测试·软件测试·人工智能·深度学习·测试工具·单元测试·ai测试工具
因_果_律2 小时前
AWS 自研 AI 芯片 Trainium3 全面解析
人工智能·云计算·aws
weixin_397578022 小时前
LLM应用开发九: 开源智能体平台
人工智能
二号小明2 小时前
AutoGLM-Phone 9B 端侧智能体:基于 vLLM 与 Docker 的云端部署与 ADB 联调指南
人工智能·计算机视觉·自然语言处理·智能手机