使用应用程序看新闻、发送消息等,都需要连接到互联网,从服务端获取数据。
那么要实现这样一种能实时从服务端获取数据的场景,就依赖于HTTP数据请求。
HTTP即超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
客户端向服务端发出一条HTTP数据请求,服务端接收请求后向客户端返回一些数据,然后客户端再对这些数据进行解析和处理。
HTTP数据请求功能主要由http模块提供,包括发起请求、中断请求、订阅/取消订阅HTTP Response Header 事件等。
在进行网络请求前,需要在module.json5文件中申明网络访问权限。
{
"module" : {
"requestPermissions":[
{
"name": "ohos.permission.INTERNET"
}
]
}
}
应用访问网络需要申请ohos.permission.INTERNET权限,因为HarmonyOS提供了一种访问控制机制即应用权限,用来保证这些数据或功能不会被不当或恶意使用。关于应用权限的的详细信息开发者可以参考:访问控制。
可以按照以下步骤完成HTTP数据请求:
导入http模块。
import http from '@ohos.net.http';
创建httpRequest对象。
使用createHttp()创建一个httpRequest对象,里面包括常用的一些网络请求方法,比如request、destroy、on('headerReceive')等。
let httpRequest = http.createHttp();
需要注意的是每一个httpRequest对象对应一个http请求任务,不可复用。
http模块支持常用的POST和GET等方法,封装在RequestMethod中。调用request方法发起网络请求,需要传入两个参数。第一个是请求的url地址,第二个是可选参数,类型为HttpRequestOptions,用于定义可选参数的类型和取值范围,包含请求方式、连接超时时间、请求头字段等。
使用Get请求,参数内容需要拼接到URL中进行发送,如下示例中在url后面拼接了两个自定义参数,分别命名为param1和param2,值分别为value1和value2:
let url= "https://EXAMPLE_URL?param1=v1¶m2=v2";
let promise = httpRequest.request(
// 请求url地址
url,
{
// 请求方式
method: http.RequestMethod.GET,
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
}
});
POST请求参数需要添加到extraData里面,如下示例中在extraData里面定义添加了两个自定义参数param1和param2,值分别为value1和value2:
let url = "https://EXAMPLE_URL";
let promise = httpRequest.request(
// 请求url地址
url,
{
// 请求方式
method: http.RequestMethod.POST,
// 请求的额外数据。
extraData: {
"param1": "value1",
"param2": "value2",
},
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
}
});
data为网络请求返回的结果,err为请求异常时返回的结果。data的类型为HttpResponse。
promise.then((data) => {
if (data.responseCode === http.ResponseCode.OK) {
console.info('Result:' + data.result);
console.info('code:' + data.responseCode);
}
}).catch((err) => {
console.info('error:' + JSON.stringify(err));
});
其中data.responseCode为http请求返回的状态码,如果状态码为http.ResponseCode.OK(即200),则表示请求成功,更多状态码可以在ResponseCode中查看。
data.result为服务器返回的业务数据,可以根据自身场景解析此数据。
在应用的开发中数据存储占据了非常重要的位置,Harmonyos系统开发中应用数据管理能力之一首选项
首选项为应用提供Key-Value键值型的数据存储能力,支持应用持久化轻量级数据,并对其进行增删除改查等。该存储对象中的数据会被缓存在内存中,因此它可以获得更快的存取速度
首选项的特点是:
1、以Key-Value形式存储数据
Key是不重复的关键字,Value是数据值。
2、非关系型数据库
区别于关系型数据库,它不保证遵循ACID(Atomicity, Consistency, Isolation and Durability)特性,数据之间无关系。
进程中每个文件仅存在一个Preferences实例,应用获取到实例后,可以从中读取数据,或者将数据存入实例中。通过调用flush方法可以将实例中的数据回写到文件里。
常用接口有
保存数据(put)、获取数据(get)、是否包含指定的key(has)、删除数据(delete)、数据持久化(flush)等,后面依次详细介绍接口使用。
1、需要导入@ohos.data.preferences模块到PreferencesUtil开发环境中,实例名字命名为dataPreferences,同时定义两个常量PREFERENCES_NAME和KEY_APP_FONT_SIZE。(注:把常用接口封装在PreferencesUtil工具类里面,为了方便后面代码直接调用)相关代码如下:
// PreferencesUtil.ets
import dataPreferences from '@ohos.data.preferences';
...
const PREFERENCES_NAME = 'myPreferences'; // 首选项名字
const KEY_APP_FONT_SIZE = 'appFontSize'; // 首选项Key字段
2、需要在entryAbility的onCreate方法获取首选项实例,以便后续能进行保存、读取、删除等操作,获取实例需要上下文context和文件名字PREFERENCES_NAME,相关代码实现如下:
// entryAbility.ets
onCreate(want, launchParam) {
Logger.info(TAG, 'onCreate');
globalThis.abilityWant = want;
// 创建首选项
PreferencesUtil.createFontPreferences(this.context);
...
}
// PreferencesUtil.ets
createFontPreferences(context) {
globalThis.getFontPreferences = (() => {
// 获取首选项实例
let preferences: Promise<dataPreferences.Preferences> = dataPreferences.getPreferences(context, PREFERENCES_NAME);
return preferences;
});
}
1、在entryAbility的onCreate方法,调用PreferencesUtil.saveDefaultFontSize保存默认数据,先用has方法判断当前key是否有存在,如果没有就通过put方法把用户数据保存起来,该方法通过key-value键值对方式保存,常量KEY_APP_FONT_SIZE作为key,用户数据fontSize作为value,再通过flush方法把数据保存到文件,相关代码如下:
// entryAbility.ets
onCreate(want, launchParam) {
Logger.info(TAG, 'onCreate');
globalThis.abilityWant = want;
...
// 设置字体默认大小
PreferencesUtil.saveDefaultFontSize(Constants.SET_SIZE_STANDARD);
}
// PreferencesUtil.ets
saveDefaultFontSize(fontSize: number) {
globalThis.getFontPreferences().then((preferences) => {
// 判断保存的key是否存在
preferences.has(KEY_APP_FONT_SIZE).then(async (isExist) => {
Logger.info(TAG, 'preferences has changeFontSize is ' + isExist);
if (!isExist) {
// 保存数据
await preferences.put(KEY_APP_FONT_SIZE, fontSize);
preferences.flush();
}
}).catch((err) => {
Logger.error(TAG, 'Has the value failed with err: ' + err);
});
}).catch((err) => {
Logger.error(TAG, 'Get the preferences failed, err: ' + err);
});
}
2、在SetFontSizePage页面,当手指移动Slider滑动条时,在onChange方法回调当前进度值,把当前进度值通过PreferencesUtil.saveChangeFontSize方法保存起来,再通过flush方法把数据保存到文件,相关代码如下:
// SetFontSizePage.ets
build() {
Row() {
Slider({
...
}).onChange((value: number) => {
// 保存当前进度值
PreferencesUtil.saveChangeFontSize(this.changeFontSize);
})
}
}
// PreferencesUtil.ets
saveChangeFontSize(fontSize: number) {
globalThis.getFontPreferences().then(async (preferences) => {
// 保存数据
await preferences.put(KEY_APP_FONT_SIZE, fontSize);
preferences.flush();
}).catch((err) => {
Logger.error(TAG, 'put the preferences failed, err: ' + err);
});
}
在HomePage的onPageShow方法,调用PreferencesUtil.getChangeFontSize方法获取用户数据,调用get方法获取,该方法通过key-value键值对方式读取,常量KEY_APP_FONT_SIZE作为key,默认数据fontSize作为value,把的到的结果赋值给变量fontSize,通过return方式把值返回去,相关代码如下:
// HomePage.ets
onPageShow() {
PreferencesUtil.getChangeFontSize().then((value) => {
this.changeFontSize = value;
Logger.info(TAG, 'Get the value of changeFontSize: ' + this.changeFontSize);
});
}
// PreferencesUtil.ets
async getChangeFontSize() {
let fontSize: number = 0;
const preferences = await globalThis.getFontPreferences();
fontSize = await preferences.get(KEY_APP_FONT_SIZE, fontSize);
return fontSize;
}
是否包含指定的key(has)
通过has方法判断首选项中是否包含指定的key,保证指定的key不会被重复保存,相关代码如下:
// PreferencesUtil.ets
saveDefaultFontSize(fontSize: number) {
globalThis.getFontPreferences().then((preferences) => {
// 判断保存的key是否存在
preferences.has(KEY_APP_FONT_SIZE).then(async (isExist) => {
Logger.info(TAG, 'preferences has changeFontSize is ' + isExist);
}).catch((err) => {
Logger.error(TAG, 'Has the value failed with err: ' + err);
});
}).catch((err) => {
Logger.error(TAG, 'Get the preferences failed, err: ' + err);
});
}
通过flush方法把应用数据保存到文件中,使得应用数据保存期限变长,相关代码如下:
// PreferencesUtil.ets
saveChangeFontSize(fontSize: number) {
globalThis.getFontPreferences().then(async (preferences) => {
// 保存数据
await preferences.put(KEY_APP_FONT_SIZE, fontSize);
// 数据持久化
preferences.flush();
}).catch((err) => {
Logger.error(TAG, 'put the preferences failed, err: ' + err);
});
}
删除首选项数据需要获取preferences实例,用delete方法删除指定的key所对应的值,常量KEY_APP_FONT_SIZE作为key,通过Promise异步回调是否删除成功,相关代码如下:
// PreferencesUtil.ets
async deleteChangeFontSize() {
const preferences: dataPreferences.Preferences = await globalThis.getFontPreferences();
// 删除数据
let deleteValue = preferences.delete(KEY_APP_FONT_SIZE);
deleteValue.then(() => {
Logger.info(TAG, 'Succeeded in deleting the key appFontSize.');
}).catch((err) => {
Logger.error(TAG, 'Failed to delete the key appFontSize. Cause: ' + err);
});
}