HarmonyOS ArkTS 新手完整复现:从环境配置到网络列表 App(超细步骤)

欢迎访问开源鸿蒙 PC 开发者社区(https://harmonypc.csdn.net/)。


摘要

本文面向零基础/初学者,完整讲清:

  1. 如何在 Windows 上配置 DevEco Studio + HarmonyOS SDK 环境;
  2. 如何新建 Empty Ability 工程;
  3. 如何实现「启动自动请求 API,展示前 10 条,含 Loading 与错误提示」;
  4. 如何 Build/Run 到模拟器或真机验收。

关键词:HarmonyOS、DevEco Studio、ArkTS、环境配置、HTTP 请求、List、ForEach


一、先决条件(你需要准备什么)

  • Windows 10/11(64 位)
  • 稳定网络(下载 SDK/组件)
  • DevEco Studio(建议最新稳定版)
  • 至少 20GB 可用磁盘空间
  • 可用设备二选一:
    • HarmonyOS 模拟器
    • HarmonyOS 真机(开启开发者选项与 USB 调试)

二、环境配置(从 0 开始)

2.1 安装 DevEco Studio

  1. 前往华为开发者官网下载安装包。
  2. 安装完成后打开 DevEco Studio。
  3. 首次启动会引导安装 SDK,请继续下一节。

2.2 安装 HarmonyOS SDK(重点)

在 DevEco Studio 中进入 SDK 管理页面(Settings/Preferences 内的 HarmonyOS SDK)。

建议安装以下组件(按你项目版本调整):

  • API 12+(你目标是鸿蒙 6.0+)
  • ArkTS 相关工具链
  • Build Tools / Command Line Tools
  • Emulator(如果要用模拟器)

如果后续出现 SDK component missing,通常是某个组件没装全或损坏,回到 SDK 管理器重新勾选安装即可。

2.3 配置 JDK(如 IDE 未自动识别)

  • DevEco 通常自带运行时,不建议新手手动乱改。
  • 若提示 JDK 问题,在 DevEco 的 JDK 设置里指向 IDE 推荐路径。

2.4 配置设备调试(真机)

  1. 手机进入开发者模式。
  2. 开启 USB 调试/允许调试安装。
  3. USB 连电脑后点「允许调试」。
  4. 在 DevEco 设备管理里看到设备在线即完成。

2.5 模拟器准备(可替代真机)

  1. 在 Device Manager 创建模拟器实例。
  2. 启动模拟器。
  3. 确保 Run 目标可选中该模拟器。

2.6 环境健康检查(建议做)

  • 新建一个最小 Empty Ability,直接 Run 一次。
  • 能在设备显示默认页面,说明环境基本 OK。
  • 这一步成功后再进入业务开发,能少踩很多坑。

2.7 Flutter 环境变量怎么确认(含你这次的实际示例)

如果你已经 git clone 了 Flutter for OpenHarmony 仓库,需要先确认 flutter 指令到底指向哪一份。

以我当前机器的示例,仓库根目录是:D:\code_flutter

A. 先查当前 flutter 路径

在 PowerShell 执行:

where flutter
flutter --version

判断标准:

  • where flutter 第一条若是 D:\code_flutter\bin\flutter.bat,说明当前就是用这份;
  • 如果不是,说明 PATH 里还有其他 Flutter,需要调整环境变量顺序。
B. 设置用户环境变量(推荐)
  1. 打开「编辑系统环境变量」->「环境变量」。
  2. 在「用户变量」新增:
    • FLUTTER_HOME = D:\code_flutter
  3. 编辑用户变量 Path,新增:
    • %FLUTTER_HOME%\bin
  4. %FLUTTER_HOME%\bin 调整到优先位置(高于旧 Flutter 路径)。
  5. 关闭并重新打开终端,再次执行:
where flutter
flutter --version
flutter doctor -v
C. 常见问题
  • where flutter 出现多个路径:删除旧路径或把新路径上移;
  • 修改后不生效:必须重开终端,必要时重启 IDE。

2.8 ArkUI-X / OpenHarmony 相关环境变量(按仓库 README 为准)

不同版本的 ArkUI-X/Flutter-OHOS 对变量名要求可能不同,但通用做法如下:

  1. 先读所用仓库的 README.md(以文档里的变量名为准)。
  2. 常见会配置:
    • JAVA_HOME(JDK 路径)
    • OHOS_SDK_HOME(HarmonyOS SDK 路径)
    • DEVECO_SDK_HOME(部分仓库会这样命名)
  3. 常见 Path 增补:
    • %JAVA_HOME%\bin
    • (若文档要求)OHOS SDK 下工具目录
  4. 配完后验证:
java -version
flutter doctor -v

注意:变量名请严格以你当前 clone 的仓库文档为准,不要混用其他文章里的旧变量名。


三、创建工程(Empty Ability)

  1. File -> New -> Create Project
  2. 选择 Empty Ability
  3. 填好项目名(例如 NetListDemo
  4. 语言选 ArkTS
  5. 创建完成后确认目录:
  • entry/src/main/module.json5
  • entry/src/main/ets/pages/Index.ets
  • entry/src/main/resources/base/profile/main_pages.json

四、实现目标功能(一步一步改)

步骤 1:配置网络权限

编辑 entry/src/main/module.json5,在顶层 module 内加入:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "usedScene": {
      "abilities": ["EntryAbility"],
      "when": "inuse"
    }
  }
]

注意:

  • 放在 module 内部;
  • 若已有 requestPermissions,请合并,不要重复键;
  • JSON5 逗号不要漏。

步骤 2:新建网络工具类

新建:entry/src/main/ets/utils/NetworkUtils.ets

import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';

/**
 * 封装 GET 请求,将响应 body 解析为 JSON
 * 若 jsonplaceholder 无法访问,可替换为其他可访问的 HTTPS 测试接口
 */
export class NetworkUtils {
  static async fetchData<T>(url: string): Promise<T> {
    const httpClient = http.createHttp();
    try {
      const response = await httpClient.request(url, {
        method: http.RequestMethod.GET,
        readTimeout: 10000,
        connectTimeout: 10000
      });
      if (response.responseCode === 200) {
        return JSON.parse(response.result as string) as T;
      }
      throw new Error(`请求失败,状态码:${response.responseCode}`);
    } catch (err) {
      const e = err as BusinessError;
      console.error(`网络请求错误:${e.code}, ${e.message}`);
      const msg = e.message && e.message.length > 0
        ? e.message
        : `网络请求失败,code:${e.code}`;
      throw new Error(msg);
    } finally {
      httpClient.destroy();
    }
  }
}

说明:ArkTS 下不要直接 throw e(任意类型),要 throw new Error(...),否则可能报 arkts-limited-throw

步骤 3:替换首页 Index.ets

编辑 entry/src/main/ets/pages/Index.ets,替换为:

import { NetworkUtils } from '../utils/NetworkUtils';

interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}

@Entry
@Component
struct Index {
  @State posts: Post[] = [];
  @State isLoading: boolean = false;
  @State error: string = '';

  aboutToAppear(): void {
    this.fetchPosts();
  }

  // 启动后拉取帖子列表
  async fetchPosts(): Promise<void> {
    this.isLoading = true;
    this.error = '';
    try {
      const data = await NetworkUtils.fetchData<Post[]>(
        'https://jsonplaceholder.typicode.com/posts'
      );
      this.posts = data.slice(0, 10);
    } catch (err) {
      this.error = '數據加載失敗,請稍後重試';
      console.error(`獲取文章列表失敗:${err}`);
    } finally {
      this.isLoading = false;
    }
  }

  build() {
    Column() {
      Text('數據清單列表')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 });

      if (this.isLoading) {
        LoadingProgress()
          .width(50)
          .height(50)
          .margin({ top: 50 });
      } else if (this.error.length > 0) {
        Text(this.error)
          .fontSize(18)
          .fontColor('#ff0000')
          .margin({ top: 50 });
      } else {
        List({ space: 12 }) {
          ForEach(this.posts, (item: Post) => {
            ListItem() {
              Column() {
                Text(`ID: ${item.id}`)
                  .fontSize(14)
                  .fontColor('#666666');
                Text(item.title)
                  .fontSize(18)
                  .fontWeight(FontWeight.Medium)
                  .margin({ top: 4 });
                Text(item.body)
                  .fontSize(14)
                  .fontColor('#999999')
                  .maxLines(2)
                  .textOverflow({ overflow: TextOverflow.Ellipsis })
                  .margin({ top: 8 });
              }
              .width('100%')
              .padding(16)
              .backgroundColor('#f5f5f5')
              .borderRadius(8);
            }
          }, (item: Post) => item.id.toString());
        }
        .width('100%')
        .layoutWeight(1)
        .padding({ left: 16, right: 16 });
      }
    }
    .width('100%')
    .height('100%')
    .padding({ top: 20 });
  }
}

步骤 4:确认首页路由

打开 entry/src/main/resources/base/profile/main_pages.json,确保:

{
  "src": [
    "pages/Index"
  ]
}

五、编译与运行(新手验收流程)

5.1 Build

菜单:Build -> Build Hap(s)/APP

如果成功,会显示构建完成日志。

5.2 Run 到设备

  1. 选择目标设备(模拟器/真机)。
  2. 点击 Run。
  3. 等待安装并自动启动应用。

5.3 验收标准(必须逐条过)

  • 启动后先短暂显示 Loading;
  • 然后出现列表(前 10 条);
  • 每项有 ID、标题、摘要(摘要 2 行省略);
  • 断网后显示红色错误提示。

六、常见问题(环境 + 代码)

1)SDK component missing

  • 回 SDK 管理器,检查 API/工具链是否完整;
  • 可尝试重新安装对应 API 组件。

2)arkts-limited-throw

  • 不要 throw e
  • 改为 throw new Error(...)

3)页面没变化

  • 检查是否改的是 entry/src/main/...
  • 检查 main_pages.json 是否仍指向 pages/Index
  • Clean Project 后重建。

4)接口无法访问

  • 先确认设备网络正常;
  • 可临时替换为其他 HTTPS 测试接口(不要改 HTTP 明文)。

七、提交/发文建议(与上一篇风格一致)

建议文章末尾加:

  • 代码仓库(AtomGit);
  • 运行截图(Build 成功、页面成功、断网报错);
  • 版本信息(DevEco 版本、API 版本、设备型号)。

八、本文修改文件清单

  • entry/src/main/module.json5
  • entry/src/main/ets/utils/NetworkUtils.ets(新增)
  • entry/src/main/ets/pages/Index.ets
  • entry/src/main/resources/base/profile/main_pages.json(校验)

九、结语

这个案例为以下链接这篇文章的先导篇,建议先看这篇文章再去实践https://blog.csdn.net/2401_83346278/article/details/159946061?spm=1001.2014.3001.5502。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐