在这里插入图片描述

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


HarmonyOS 网络请求与数据持久化

前言

HarmonyOS 应用开发中,网络请求和数据持久化是两类最常用的能力:前者用于拉取服务端数据,后者用于在本地缓存用户数据、配置等。ArkTS 侧通过 @ohos.net.http@ohos.request 等模块发请求,通过 @ohos.data.preferences、关系型数据库等做持久化。

本文只讲这两块的核心 API 和典型用法,并给出关键代码与注意点,不贴完整 Demo。

网络请求

使用 http 模块发 GET 请求

@ohos.net.http 提供 createHttp(),得到 httpRequest 对象后可发起请求。典型流程:创建 → 设置 URL/方法/头 → 请求 → 关闭。

import http from '@ohos.net.http'

// 在页面或异步方法中
const httpRequest = http.createHttp()

httpRequest.request(
  'https://api.example.com/list',
  {
    method: http.RequestMethod.GET,
    header: { 'Content-Type': 'application/json' },
    connectTimeout: 60000,
    readTimeout: 60000
  },
  (err, data) => {
    if (err) {
      console.error('请求失败', err)
      return
    }
    if (data.responseCode === 200) {
      const result = JSON.parse(data.result as string)
      // 更新 @State,驱动 UI 刷新
    }
    httpRequest.destroy()
  }
)

要点:

  • 回调在子线程执行:若要在回调里更新 @State、刷新 UI,需要封装成 runOnUIThread 或使用异步封装(见下)
  • 务必 destroy:请求完成后调用 httpRequest.destroy(),避免泄漏
  • 超时connectTimeoutreadTimeout 按需设置,单位毫秒

在 UI 线程中更新结果

ArkTS 中 UI 只能在主线程更新,而 http 回调可能在工作线程,因此需要把「结果处理 + 状态更新」抛回主线程:

import { runOnUIThread } from '@kit/ArkUI'

// 在 request 的回调里
if (data.responseCode === 200) {
  const list = JSON.parse(data.result as string)
  runOnUIThread(() => {
    this.listData = list  // this 指向 @Component,listData 为 @State
  })
}

这样 this.listData 的变更会在主线程执行,触发界面刷新。

POST 与请求体

POST 请求只需把 method 改为 http.RequestMethod.POST,并在 extraData 里传 body 字符串:

httpRequest.request(
  'https://api.example.com/submit',
  {
    method: http.RequestMethod.POST,
    header: { 'Content-Type': 'application/json' },
    extraData: JSON.stringify({ name: 'test', id: 1 }),
    connectTimeout: 60000,
    readTimeout: 60000
  },
  (err, data) => {
    // 同上,err/data 处理 + destroy
  }
)

服务端若要求表单编码,则 Content-Type 改为 application/x-www-form-urlencodedextraData 改为 key1=value1&key2=value2 等形式。

封装为 Promise(可选)

为避免回调嵌套、便于在 async 函数里使用,可对 request 做一层 Promise 封装:

function request<T>(url: string, options: http.HttpRequestOptions): Promise<T> {
  const req = http.createHttp()
  return new Promise((resolve, reject) => {
    req.request(url, options, (err, data) => {
      req.destroy()
      if (err) {
        reject(err)
        return
      }
      if (data.responseCode >= 200 && data.responseCode < 300) {
        try {
          resolve(JSON.parse(data.result as string) as T)
        } catch (e) {
          reject(e)
        }
      } else {
        reject(new Error(`HTTP ${data.responseCode}`))
      }
    })
  })
}

在页面里 await request<RespType>(url, opts) 得到结果后,再在 runOnUIThread 里赋给 @State 即可。

数据持久化

Preferences 轻量键值存储

@ohos.data.preferences 适用于配置项、简单键值对,数据以文件形式存在应用沙箱内。

获取与读写:

import dataPreferences from '@ohos.data.preferences'
import { common } from '@kit.AbilityKit'

// 在 EntryAbility 或异步上下文中
const context = getContext(this) as common.UIAbilityContext
const store = await dataPreferences.getPreferences(context, 'my_prefs')

// 写
await store.put('token', 'xxx')
await store.put('userId', 100)
await store.flush()

// 读
const token = await store.get('token', '')
const userId = await store.get('userId', 0)

注意:

  • getPreferences 为异步,需在 async 函数或 Promise 中调用
  • 写入后建议调用 flush() 保证落盘
  • 键为 string,值为 string | number | boolean 等基础类型

在页面中的用法:aboutToAppear() 里异步 getPreferencesget,结果赋给 @State;在用户操作(如登录成功)时 put + flush,即可实现「打开应用读缓存、操作后写缓存」。

关系型数据库(RDB)简要

需要本地表结构、查询条件时,可使用关系型数据库。流程一般为:获取 RdbStore → 建表(若不存在)→ insert/update/query/delete。

获取 RdbStore:

import relationalStore from '@ohos.data.relationalStore'

const config: relationalStore.StoreConfig = {
  name: 'app.db',
  securityLevel: relationalStore.SecurityLevel.S1
}
const store = await relationalStore.getRdbStore(context, config)

建表与插入:

const sqlCreate = `
  CREATE TABLE IF NOT EXISTS user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    age INTEGER
  )
`
await store.executeSql(sqlCreate)

const valueBucket: relationalStore.ValuesBucket = {
  name: '张三',
  age: 20
}
await store.insert('user', valueBucket)

查询:

const predicates = new relationalStore.RdbPredicates('user')
predicates.equalTo('age', 20)
const resultSet = await store.query(predicates, ['id', 'name', 'age'])
while (resultSet.goToNextRow()) {
  const id = resultSet.getLong(resultSet.getColumnIndex('id'))
  const name = resultSet.getString(resultSet.getColumnIndex('name'))
  // 使用 id, name...
}
resultSet.close()

RDB 适合列表、草稿、离线缓存等结构化数据;简单配置仍建议用 Preferences,两者可搭配使用。

总结

  • 网络http.createHttp() 发请求,回调中注意线程(用 runOnUIThread 更新 UI)和及时 destroy;可按需封装为 Promise。
  • 持久化:配置/简单键值用 dataPreferences.getPreferences 的 put/get + flush;结构化数据用 RDB 建表 + insert/query。

把「请求 → 解析 → 主线程更新 @State」和「启动读 Preferences/RDB、操作后写回」串起来,即可覆盖大部分 HarmonyOS 应用的数据与持久化场景。

Logo

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

更多推荐