一、网络编程基础与权限配置
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 {
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(url: string, headers?: Object): Promise> {
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(url: string, data: Object, headers?: Object): Promise> {
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 {
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 {
try {
const response = await this.httpClient.get(
`${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 {
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 {
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 {
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.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 {
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 {
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 {
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 {
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(key: string, defaultValue: T): Promise {
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 {
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 {
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 {
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 {
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 {
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 {
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): Promise {
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 {
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 {
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(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 {
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 {
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(url: string, cacheKey: string): Promise {
// 首先检查缓存
const cachedData = await this.getFromCache(cacheKey);
if (cachedData && !this.isCacheExpired(cachedData.timestamp)) {
return cachedData.data;
}
// 缓存无效或不存在,从网络获取
try {
const response = await this.httpClient.get(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(key: string): Promise {
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 {
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 {
await this.preferences.delete(key);
}
// 清空所有缓存
async clearAllCache(): Promise {
await this.preferences.clear();
}
}
⚠️ 七、安全最佳实践
1. HTTPS证书验证
import ssl from '@ohos.net.ssl';
class SecurityManager {
static async configureSSL(): Promise {
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 {
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 {
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 {
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应用。这些技术为应用提供了稳定可靠的数据管理和通信能力,是开发现代移动应用的核心基础。
需要参加鸿蒙认证的请点击 鸿蒙认证链接