🔥 关键词:鸿蒙网络请求、HTTP、Preferences、关系型数据库、数据持久化

前言

现代应用离不开网络交互和数据存储。HarmonyOS提供了完善的网络请求API和多种数据持久化方案。

本文将详细介绍如何在ArkTS中进行HTTP请求、处理JSON数据,以及使用Preferences和数据库进行本地存储。


一、HTTP网络请求

1.1 导入网络模块

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

1.2 发送GET请求

async function fetchUserInfo(userId: string): Promise<void> {
  // 创建HTTP请求对象
  let httpRequest = http.createHttp()
  
  // 请求URL
  let url = `https://api.example.com/users/${userId}`
  
  try {
    // 发送请求
    let response = await httpRequest.request(url, {
      method: http.RequestMethod.GET,
      header: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer your_token'
      },
      connectTimeout: 60000,    // 连接超时
      readTimeout: 60000        // 读取超时
    })
    
    // 处理响应
    if (response.responseCode === 200) {
      let data = JSON.parse(response.result as string)
      console.info('用户信息:', JSON.stringify(data))
    } else {
      console.error('请求失败:', response.responseCode)
    }
  } catch (error) {
    let err = error as BusinessError
    console.error('请求异常:', err.message)
  } finally {
    // 销毁请求对象
    httpRequest.destroy()
  }
}

1.3 发送POST请求

async function login(username: string, password: string): Promise<void> {
  let httpRequest = http.createHttp()
  
  let requestBody = {
    username: username,
    password: password
  }
  
  try {
    let response = await httpRequest.request(
      'https://api.example.com/login',
      {
        method: http.RequestMethod.POST,
        header: {
          'Content-Type': 'application/json'
        },
        extraData: JSON.stringify(requestBody)
      }
    )
    
    if (response.responseCode === 200) {
      let result = JSON.parse(response.result as string)
      // 保存token
      AppStorage.Set('token', result.token)
      console.info('登录成功')
    }
  } catch (error) {
    console.error('登录失败:', error)
  } finally {
    httpRequest.destroy()
  }
}

二、封装网络请求工具类

为了提高代码复用性,建议封装一个网络请求工具类:

class HttpClient {
  private static baseUrl: string = 'https://api.example.com'
  private static token: string = ''

  // 设置token
  static setToken(token: string) {
    HttpClient.token = token
  }

  // 通用请求方法
  static async request<T>(
    url: string,
    method: http.RequestMethod,
    data?: object
  ): Promise<T> {
    return new Promise((resolve, reject) => {
      let httpRequest = http.createHttp()
      
      let fullUrl = HttpClient.baseUrl + url
      
      let headers: Record<string, string> = {
        'Content-Type': 'application/json'
      }
      
      if (HttpClient.token) {
        headers['Authorization'] = `Bearer ${HttpClient.token}`
      }
      
      httpRequest.request(
        fullUrl,
        {
          method: method,
          header: headers,
          extraData: data ? JSON.stringify(data) : ''
        },
        (err, data) => {
          httpRequest.destroy()
          
          if (err) {
            reject(err)
            return
          }
          
          if (data.responseCode === 200) {
            resolve(JSON.parse(data.result as string))
          } else {
            reject(new Error(`HTTP ${data.responseCode}`))
          }
        }
      )
    })
  }

  // GET请求
  static get<T>(url: string): Promise<T> {
    return HttpClient.request<T>(url, http.RequestMethod.GET)
  }

  // POST请求
  static post<T>(url: string, data: object): Promise<T> {
    return HttpClient.request<T>(url, http.RequestMethod.POST, data)
  }
}

三、Preferences轻量级存储

Preferences适合存储简单的键值对数据:

import dataPreferences from '@ohos.data.preferences'

class PreferencesUtil {
  private static preferences: dataPreferences.Preferences | null = null

  // 初始化
  static async init(context: Context) {
    PreferencesUtil.preferences = await dataPreferences.getPreferences(
      context,
      'MyAppPreferences'
    )
  }

  // 保存数据
  static async put(key: string, value: string | number | boolean) {
    if (!PreferencesUtil.preferences) return
    await PreferencesUtil.preferences.put(key, value)
    await PreferencesUtil.preferences.flush()
  }

  // 获取数据
  static async get(key: string, defaultValue?: string): Promise<string | undefined> {
    if (!PreferencesUtil.preferences) return defaultValue
    return await PreferencesUtil.preferences.get(key, defaultValue)
  }

  // 删除数据
  static async delete(key: string) {
    if (!PreferencesUtil.preferences) return
    await PreferencesUtil.preferences.delete(key)
    await PreferencesUtil.preferences.flush()
  }
}

// 使用示例
async function saveUserData(user: UserInfo) {
  await PreferencesUtil.put('userId', user.id)
  await PreferencesUtil.put('userName', user.name)
  await PreferencesUtil.put('isLogin', true)
}

async function getUserData() {
  let userId = await PreferencesUtil.get('userId', '')
  let userName = await PreferencesUtil.get('userName', '')
  return { userId, userName }
}

四、关系型数据库

对于复杂数据,可以使用关系型数据库:

import relationalStore from '@ohos.data.relationalStore'

class DatabaseHelper {
  private static rdbStore: relationalStore.RdbStore | null = null
  private static readonly STORE_NAME = 'TodoDB'

  // 初始化数据库
  static async init(context: Context) {
    const config: relationalStore.StoreConfig = {
      name: DatabaseHelper.STORE_NAME,
      securityLevel: relationalStore.SecurityLevel.S1
    }
    
    DatabaseHelper.rdbStore = await relationalStore.getRdbStore(
      context,
      config
    )
    
    // 创建表
    const createTableSQL = `
      CREATE TABLE IF NOT EXISTS todos (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        completed INTEGER DEFAULT 0,
        createTime INTEGER
      )
    `
    await DatabaseHelper.rdbStore.executeSql(createTableSQL)
  }

  // 插入数据
  static async insertTodo(todo: Todo): Promise<number> {
    if (!DatabaseHelper.rdbStore) return -1
    
    const valueBucket: relationalStore.ValuesBucket = {
      title: todo.title,
      completed: todo.completed ? 1 : 0,
      createTime: Date.now()
    }
    
    return await DatabaseHelper.rdbStore.insert('todos', valueBucket)
  }

  // 查询数据
  static async queryTodos(): Promise<Todo[]> {
    if (!DatabaseHelper.rdbStore) return []
    
    const predicates = new relationalStore.RdbPredicates('todos')
    predicates.orderByDesc('createTime')
    
    const resultSet = await DatabaseHelper.rdbStore.query(predicates)
    let todos: Todo[] = []
    
    while (resultSet.goToNextRow()) {
      todos.push({
        id: resultSet.getLong(resultSet.getColumnIndex('id')),
        title: resultSet.getString(resultSet.getColumnIndex('title')),
        completed: resultSet.getLong(resultSet.getColumnIndex('completed')) === 1,
        createTime: resultSet.getLong(resultSet.getColumnIndex('createTime'))
      })
    }
    resultSet.close()
    return todos
  }
}

五、网络请求权限配置

module.json5中配置网络权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}

总结

本文详细介绍了HarmonyOS中的网络请求和数据持久化方案。通过http模块可以轻松实现HTTP通信,Preferences适合轻量级数据存储,而关系型数据库则能满足复杂数据的存储需求。

下一篇文章将带你完成一个完整的待办清单App项目,综合运用所学知识。


Logo

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

更多推荐