当前位置: 首页 > news >正文

HarmonyOS 5 网络编程与数据存储实战:从RESTful API到本地持久化

🌐 一、网络编程基础与权限配置

HarmonyOS提供了强大的网络能力,支持HTTP/HTTPS、WebSocket、Socket等协议。

1. 权限声明与配置

module.json5中声明网络权限和加密通信权限:

{"module": {"requestPermissions": [{"name": "ohos.permission.INTERNET","reason": "$string:internet_permission_reason"},{"name": "ohos.permission.GET_NETWORK_INFO","reason": "$string:network_info_permission_reason"}]}
}

2. 网络状态检测

在进行网络请求前,先检测当前网络状态:

import netConnection from '@ohos.net.connection';
import { BusinessError } from '@ohos.base';class NetworkUtils {static async isNetworkAvailable(): Promise<boolean> {try {const netCap = await netConnection.getDefaultNet();if (!netCap) {return false;}const netInfo = await netConnection.getConnectionProperties(netCap);return netInfo.isAvailable;} catch (error) {console.error(`Check network failed: ${(error as BusinessError).message}`);return false;}}static getNetworkType(): string {const netCap = netConnection.getDefaultNetSync();return netCap ? netCap.type : 'unknown';}
}

📡 二、HTTP/HTTPS 客户端编程

1. 使用 @ohos.net.http模块

import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';class HttpClient {private request: http.HttpRequest = http.createHttp();// GET请求示例async get<T>(url: string, headers?: Object): Promise<HttpResponse<T>> {try {if (!await NetworkUtils.isNetworkAvailable()) {throw new Error('Network not available');}const options: http.HttpRequestOptions = {method: http.RequestMethod.GET,header: headers,connectTimeout: 30000,readTimeout: 30000};const response = await this.request.request(url, options);return {code: response.responseCode,data: JSON.parse(response.result as string) as T,headers: response.header};} catch (error) {throw new Error(`HTTP GET failed: ${(error as BusinessError).message}`);}}// POST请求示例async post<T>(url: string, data: Object, headers?: Object): Promise<HttpResponse<T>> {try {const options: http.HttpRequestOptions = {method: http.RequestMethod.POST,header: {'Content-Type': 'application/json',...headers},extraData: JSON.stringify(data),connectTimeout: 30000,readTimeout: 30000};const response = await this.request.request(url, options);return {code: response.responseCode,data: JSON.parse(response.result as string) as T,headers: response.header};} catch (error) {throw new Error(`HTTP POST failed: ${(error as BusinessError).message}`);}}// 销毁请求对象destroy(): void {this.request.destroy();}
}interface HttpResponse<T> {code: number;data: T;headers: Object;
}

2. 实战:天气API调用示例

interface WeatherData {city: string;temperature: number;condition: string;humidity: number;windSpeed: number;
}class WeatherService {private httpClient: HttpClient = new HttpClient();private baseUrl: string = 'https://api.weather.com/v3';async getCurrentWeather(city: string): Promise<WeatherData> {try {const response = await this.httpClient.get<WeatherData>(`${this.baseUrl}/current?city=${encodeURIComponent(city)}`);if (response.code === 200) {return response.data;} else {throw new Error(`Weather API error: ${response.code}`);}} catch (error) {console.error('Failed to fetch weather:', error);// 返回缓存数据或默认数据return this.getCachedWeatherData(city);}}private getCachedWeatherData(city: string): WeatherData {// 从本地存储获取缓存的天气数据return {city: city,temperature: 25,condition: 'Cloudy',humidity: 60,windSpeed: 5};}
}

3. 文件下载与上传

class FileTransferService {private httpClient: HttpClient = new HttpClient();// 文件下载async downloadFile(url: string, filePath: string): Promise<void> {try {const options: http.HttpRequestOptions = {method: http.RequestMethod.GET,connectTimeout: 60000,readTimeout: 60000};const response = await this.httpClient.request(url, options);if (response.responseCode === 200) {// 将文件内容写入本地文件系统await this.saveFile(response.result as ArrayBuffer, filePath);}} catch (error) {throw new Error(`Download failed: ${(error as BusinessError).message}`);}}// 文件上传async uploadFile(url: string, filePath: string, formData: Object): Promise<void> {try {const fileContent = await this.readFile(filePath);const options: http.HttpRequestOptions = {method: http.RequestMethod.POST,header: {'Content-Type': 'multipart/form-data'},extraData: {...formData,file: fileContent},connectTimeout: 60000,readTimeout: 60000};await this.httpClient.request(url, options);} catch (error) {throw new Error(`Upload failed: ${(error as BusinessError).message}`);}}
}

🔌 三、WebSocket 实时通信

对于需要实时数据交换的场景,WebSocket是更好的选择。

import webSocket from '@ohos.net.webSocket';class WebSocketClient {private socket: webSocket.WebSocket | null = null;private reconnectAttempts: number = 0;private maxReconnectAttempts: number = 5;// 连接WebSocket服务器async connect(url: string): Promise<void> {try {this.socket = await webSocket.createWebSocket();// 注册事件监听器this.socket.on('open', () => {console.info('WebSocket connected');this.reconnectAttempts = 0;});this.socket.on('message', (data: string | ArrayBuffer) => {this.handleMessage(data);});this.socket.on('close', () => {console.info('WebSocket closed');this.handleReconnection(url);});this.socket.on('error', (err: Error) => {console.error('WebSocket error:', err);});// 建立连接await this.socket.connect(url);} catch (error) {console.error('WebSocket connection failed:', error);this.handleReconnection(url);}}// 发送消息sendMessage(message: string | ArrayBuffer): void {if (this.socket && this.socket.readyState === webSocket.ReadyState.OPEN) {this.socket.send(message);}}// 处理接收到的消息private handleMessage(data: string | ArrayBuffer): void {try {const message = typeof data === 'string' ? data : new TextDecoder().decode(data);const parsedData = JSON.parse(message);// 分发消息到各个处理器this.dispatchMessage(parsedData);} catch (error) {console.error('Failed to parse WebSocket message:', error);}}// 重连机制private handleReconnection(url: string): void {if (this.reconnectAttempts < this.maxReconnectAttempts) {this.reconnectAttempts++;const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);setTimeout(() => {this.connect(url);}, delay);}}// 关闭连接close(): void {if (this.socket) {this.socket.close();this.socket = null;}}
}

💾 四、数据持久化存储

1. 轻量级数据存储(Preferences)

适用于存储简单的键值对数据。

import preferences from '@ohos.data.preferences';class PreferencesManager {private pref: preferences.Preferences | null = null;private readonly prefName: string = 'my_app_preferences';// 初始化Preferences实例async initialize(context: Context): Promise<void> {try {this.pref = await preferences.getPreferences(context, this.prefName);} catch (error) {console.error('Failed to initialize preferences:', error);}}// 存储字符串数据async putString(key: string, value: string): Promise<boolean> {if (!this.pref) return false;try {await this.pref.put(key, value);await this.pref.flush();return true;} catch (error) {console.error('Failed to put string:', error);return false;}}// 获取字符串数据async getString(key: string, defaultValue: string = ''): Promise<string> {if (!this.pref) return defaultValue;try {return await this.pref.get(key, defaultValue) as string;} catch (error) {console.error('Failed to get string:', error);return defaultValue;}}// 存储对象数据(自动序列化为JSON)async putObject(key: string, value: Object): Promise<boolean> {try {const jsonString = JSON.stringify(value);return await this.putString(key, jsonString);} catch (error) {console.error('Failed to put object:', error);return false;}}// 获取对象数据(自动从JSON反序列化)async getObject<T>(key: string, defaultValue: T): Promise<T> {try {const jsonString = await this.getString(key, '');if (jsonString) {return JSON.parse(jsonString) as T;}return defaultValue;} catch (error) {console.error('Failed to get object:', error);return defaultValue;}}// 删除数据async delete(key: string): Promise<boolean> {if (!this.pref) return false;try {await this.pref.delete(key);await this.pref.flush();return true;} catch (error) {console.error('Failed to delete preference:', error);return false;}}// 清空所有数据async clear(): Promise<boolean> {if (!this.pref) return false;try {await this.pref.clear();await this.pref.flush();return true;} catch (error) {console.error('Failed to clear preferences:', error);return false;}}
}

2. 关系型数据库(RDB Store)

适用于存储结构化数据,支持SQL查询。

import relationalStore from '@ohos.data.relationalStore';interface User {id?: number;name: string;email: string;age: number;createdAt: number;
}class DatabaseManager {private rdbStore: relationalStore.RdbStore | null = null;private readonly dbName: string = 'my_app.db';private readonly dbVersion: number = 1;// 初始化数据库async initialize(context: Context): Promise<void> {const config: relationalStore.StoreConfig = {name: this.dbName,securityLevel: relationalStore.SecurityLevel.S1};try {this.rdbStore = await relationalStore.getRdbStore(context, config);await this.createTables();} catch (error) {console.error('Failed to initialize database:', error);}}// 创建数据表private async createTables(): Promise<void> {if (!this.rdbStore) return;const createUserTable = `CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,email TEXT UNIQUE NOT NULL,age INTEGER,created_at INTEGER)`;try {await this.rdbStore.executeSql(createUserTable);} catch (error) {console.error('Failed to create table:', error);}}// 插入用户数据async insertUser(user: User): Promise<number> {if (!this.rdbStore) return -1;const valuesBucket: relationalStore.ValuesBucket = {'name': user.name,'email': user.email,'age': user.age,'created_at': Date.now()};try {return await this.rdbStore.insert('users', valuesBucket);} catch (error) {console.error('Failed to insert user:', error);return -1;}}// 查询用户数据async queryUsers(query: string = '', params: any[] = []): Promise<User[]> {if (!this.rdbStore) return [];let sql = 'SELECT * FROM users';if (query) {sql += ` WHERE ${query}`;}try {const resultSet = await this.rdbStore.query(sql, params);const users: User[] = [];while (!resultSet.isAtLastRow) {await resultSet.goToNextRow();users.push({id: resultSet.getLong(resultSet.getColumnIndex('id')),name: resultSet.getString(resultSet.getColumnIndex('name')),email: resultSet.getString(resultSet.getColumnIndex('email')),age: resultSet.getLong(resultSet.getColumnIndex('age')),createdAt: resultSet.getLong(resultSet.getColumnIndex('created_at'))});}resultSet.close();return users;} catch (error) {console.error('Failed to query users:', error);return [];}}// 更新用户数据async updateUser(id: number, updates: Partial<User>): Promise<boolean> {if (!this.rdbStore) return false;const valuesBucket: relationalStore.ValuesBucket = { ...updates };const predicates = relationalStore.RdbPredicates('users');predicates.equalTo('id', id);try {const rowsUpdated = await this.rdbStore.update(valuesBucket, predicates);return rowsUpdated > 0;} catch (error) {console.error('Failed to update user:', error);return false;}}// 删除用户async deleteUser(id: number): Promise<boolean> {if (!this.rdbStore) return false;const predicates = relationalStore.RdbPredicates('users');predicates.equalTo('id', id);try {const rowsDeleted = await this.rdbStore.delete(predicates);return rowsDeleted > 0;} catch (error) {console.error('Failed to delete user:', error);return false;}}
}

🔄 五、分布式数据管理

HarmonyOS的分布式能力允许数据在多个设备间自动同步。

import distributedKVStore from '@ohos.data.distributedKVStore';class DistributedDataManager {private kvManager: distributedKVStore.KVManager | null = null;private kvStore: distributedKVStore.SingleKVStore | null = null;private readonly storeId: string = 'distributed_app_data';// 初始化分布式数据库async initialize(context: Context): Promise<void> {try {// 创建KVManager实例const kvManagerConfig: distributedKVStore.Config = {bundleName: context.applicationInfo.name,userInfo: {userId: '0',userType: distributedKVStore.UserType.SAME_USER_ID}};this.kvManager = distributedKVStore.createKVManager(kvManagerConfig);// 创建KVStore实例const options: distributedKVStore.StoreConfig = {storeId: this.storeId,kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,securityLevel: distributedKVStore.SecurityLevel.S2,autoSync: true,encrypt: false};this.kvStore = await this.kvManager.getKVStore<distributedKVStore.SingleKVStore>(options);// 注册数据变更监听器await this.kvStore.on('dataChange', distributedKVStore.SubscribeType.SUBSCRIBE_TYPE_ALL, (data: distributedKVStore.ChangeData) => {this.handleDataChange(data);});} catch (error) {console.error('Failed to initialize distributed data manager:', error);}}// 存储数据async put(key: string, value: any): Promise<boolean> {if (!this.kvStore) return false;try {const serializedValue = JSON.stringify(value);await this.kvStore.put(key, serializedValue);return true;} catch (error) {console.error('Failed to put distributed data:', error);return false;}}// 获取数据async get(key: string, defaultValue: any = null): Promise<any> {if (!this.kvStore) return defaultValue;try {const entries = await this.kvStore.getEntries(key);if (entries.length > 0) {const value = entries[0].value.value as string;return JSON.parse(value);}return defaultValue;} catch (error) {console.error('Failed to get distributed data:', error);return defaultValue;}}// 处理数据变更private handleDataChange(data: distributedKVStore.ChangeData): void {try {const changedData = JSON.parse(data.value as string);console.info(`Data changed: ${data.key} = ${JSON.stringify(changedData)}`);// 通知应用其他部分数据已更新this.notifyDataChange(data.key, changedData);} catch (error) {console.error('Failed to handle data change:', error);}}// 数据变更通知private notifyDataChange(key: string, newValue: any): void {// 使用EventEmitter或其他机制通知应用其他组件}
}

🧪 六、实战示例:网络缓存策略

结合网络请求和本地存储实现智能缓存策略。

class CachedApiService {private httpClient: HttpClient = new HttpClient();private preferences: PreferencesManager = new PreferencesManager();private readonly cacheTimeout: number = 5 * 60 * 1000; // 5分钟缓存// 获取带缓存的数据async getWithCache<T>(url: string, cacheKey: string): Promise<T> {// 首先检查缓存const cachedData = await this.getFromCache<T>(cacheKey);if (cachedData && !this.isCacheExpired(cachedData.timestamp)) {return cachedData.data;}// 缓存无效或不存在,从网络获取try {const response = await this.httpClient.get<T>(url);if (response.code === 200) {// 缓存新数据await this.saveToCache(cacheKey, response.data);return response.data;}throw new Error(`API returned ${response.code}`);} catch (error) {// 网络请求失败,返回缓存数据(即使可能过期)if (cachedData) {console.warn('Using stale cache due to network error');return cachedData.data;}throw error;}}// 从缓存获取数据private async getFromCache<T>(key: string): Promise<{ data: T; timestamp: number } | null> {try {return await this.preferences.getObject(key, null);} catch (error) {console.error('Failed to get from cache:', error);return null;}}// 保存数据到缓存private async saveToCache(key: string, data: any): Promise<void> {try {const cacheItem = {data: data,timestamp: Date.now()};await this.preferences.putObject(key, cacheItem);} catch (error) {console.error('Failed to save to cache:', error);}}// 检查缓存是否过期private isCacheExpired(timestamp: number): boolean {return Date.now() - timestamp > this.cacheTimeout;}// 清空特定缓存async clearCache(key: string): Promise<void> {await this.preferences.delete(key);}// 清空所有缓存async clearAllCache(): Promise<void> {await this.preferences.clear();}
}

⚠️ 七、安全最佳实践

1. HTTPS证书验证

import ssl from '@ohos.net.ssl';class SecurityManager {static async configureSSL(): Promise<void> {try {// 加载自定义证书const certData = await this.loadCertificate();const keyStore = ssl.createX509KeyStore();await keyStore.init(certData);// 配置SSL选项const sslOptions: ssl.SSLOptions = {keyStore: keyStore,protocols: [ssl.Protocol.TLSV1_2, ssl.Protocol.TLSV1_3],cipherSuites: ['TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256','TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384']};// 应用全局SSL配置ssl.setSSLOptions(sslOptions);} catch (error) {console.error('Failed to configure SSL:', error);}}
}

2. 数据加密存储

import cryptoFramework from '@ohos.security.crypto';class DataEncryptor {private readonly algorithm: string = 'AES256';private readonly key: cryptoFramework.SymKey | null = null;// 初始化加密密钥async initialize(): Promise<void> {try {const keyGenerator = cryptoFramework.createSymKeyGenerator('AES256');const keyOptions: cryptoFramework.SymKeyGeneratorOptions = {algName: 'AES256',keySize: 256};this.key = await keyGenerator.generateSymKey(keyOptions);} catch (error) {console.error('Failed to initialize encryptor:', error);}}// 加密数据async encrypt(data: string): Promise<string> {if (!this.key) throw new Error('Encryptor not initialized');try {const cipher = cryptoFramework.createCipher('AES256|ECB|PKCS7');await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, this.key, null);const input: cryptoFramework.DataBlob = { data: new TextEncoder().encode(data) };const encrypted = await cipher.doFinal(input);return this.arrayBufferToBase64(encrypted.data);} catch (error) {throw new Error(`Encryption failed: ${error}`);}}// 解密数据async decrypt(encryptedData: string): Promise<string> {if (!this.key) throw new Error('Encryptor not initialized');try {const decipher = cryptoFramework.createCipher('AES256|ECB|PKCS7');await decipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, this.key, null);const input: cryptoFramework.DataBlob = { data: this.base64ToArrayBuffer(encryptedData) };const decrypted = await decipher.doFinal(input);return new TextDecoder().decode(decrypted.data);} catch (error) {throw new Error(`Decryption failed: ${error}`);}}
}

通过掌握这些网络编程和数据存储技术,你能够构建出功能丰富、性能优异且数据安全的HarmonyOS应用。这些技术为应用提供了稳定可靠的数据管理和通信能力,是开发现代移动应用的核心基础。

需要参加鸿蒙认证的请点击 鸿蒙认证链接

http://www.hskmm.com/?act=detail&tid=15951

相关文章:

  • 【光照】[环境光ambient]以UnityURP为例
  • 浅谈当前时代下大学生的就业择业及人生规划
  • 实用指南:玳瑁的嵌入式日记---0923(ARM)
  • 个人博客搭建记录【hexo】
  • 喵喵喵
  • flink不同环境切换 - --
  • ps-填充色
  • HarmonyOS 5分布式数据同步实战:跨设备待办事项应用
  • 深入理解HarmonyOS 5的AVSession:构建跨设备媒体播放器
  • Extjs小例子
  • 匿名函数
  • HarmonyOS资源管理与访问:多分辨率与多语言适配
  • 面试官:为什么没有虚拟线程池?
  • 润生软件简介:以“重构与共生”引领商业未来
  • Python 并发编程
  • 安装pyautogui时与setuptool时冲突报错-module setuptools.dist has no attribute check_test_suite
  • 统计机器学习经典分类算法MATLAB实现
  • 从安装到中文界面,一文带你玩转 DaVinci Resolve 20(零基础也能搞定)
  • 靶场1
  • 299、已凉
  • linux手动安装阿里云Logtail采集Nginx访问日志
  • WPF的数据绑定之通知修改
  • 古代史
  • matlab运行时遇到的license问题
  • HarmonyOS 5.0+ 安全加密与数据存储最佳实践指南
  • EV论文修改工作
  • HarmonyOS之设备硬件能力调用:传感器、蓝牙与定位
  • 基于HarmonyOS SDK开放能力的微博社交体验构建实践
  • web三维
  • HarmonyOS 多线程编程:Worker 使用与性能优化指南