赞
踩
应用的开发离不开网络请求,因为我们不可能把所有数据都存储在本地,因此应用需要跟数据进行远程交互。而HarmonyOS也为开发者提供了网络管理模块,分别提供了以下功能:
本文主要讲一下http请求的使用,其它具体请查阅官方文档
import http from "@oos.net.http"
// 创建一个http的请求对象,不可复用 const httpRequest = http.createHttp() // httpRequest.request(url, HttpRequestOptions) // 发起网络请求 httpRequest.request( "http://localhost:8080/users", // 请求URL路径 { method: http.RequestMethod.GET, extraData: {"param1": value1} // k1=v1&k2=v2 } ) // 处理响应结果 .then((resp: http.HttpResponse) => { if (resp.responseCode == 200) { // 请求成功 } }) .catch((err: Error) => { // 请求失败 })
参数HttpRequestOptions具体参数属性
名称 | 类型 | 描述 |
---|---|---|
method | RequestMethod | 请求方式,GET、POST、PUT、DELETE等 |
extraData | string|Object | 请求参数 |
header | Object | 请求头字段 |
connectTimeout | number | 连接超时时间,单位毫秒,默认是60000ms |
readTimeout | number | 读取超时间,同上 |
请求返回结果HttpResponse具体属性值
名称 | 类型 | 描述 |
---|---|---|
responseCode | ResponseCode | 响应状态码 |
header | Object | 响应头 |
cookies | string | 响应返回的cookies |
result | string|Object | 响应体,默认是JSON字符串 |
resultType | HttpDataType | 返回值类型 |
因为axios属于第三方库,需要使用到HarmonyOS提供的第三方包管理工具:ohpm,具体查看官方文档
步骤1:下载和安装ohpm
# windows 环境
init.bat
# Linux或Mac环境
./init.sh
# windows 环境,直接在我的电脑配置即可
直接在系统变量的Path下加入你的ohpm安装路径即可,
如:D:\software\Huawei\command-line-tools\ohpm\bin
# Linux或Mac环境,其中OHPM的路径请替换为ohpm的安装路径
export OHPM_HOME=/XX/ohpm
export PATH=${OHPM_HOME}/bin:${PATH}
步骤2:下载和安装axios
# 进入项目目录,然后使用命令行
ohpm install @ohos/axios
{
"module": {
"requestPermission": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
步骤3:使用axios (前端同学最熟悉了)
下面简单介绍一下axios的使用
导入axios
import axios from "@ohos/axios"
发送请求,并处理响应
axios.get( 'url', { params: { param1: 'value1' }, data: { param1: 'value1' } } ) .then(response => { if (response.status !== 200) { console.log('查询失败') return false } console.log('查询成功') }) .catch(err => { console.log('查询失败', JSON.stringify(err)) })
import dataPreference from '@ohos.data.preferences'
dataPreference.getPreferences(this.context, 'MyAppPreferences')
.then(peferences => {
// 获取成功
})
.catch(reason => {
// 获取失败
})
// 写入数据,如果已经存在则会覆盖,可利用.has()判断是否存在
preferences.put('key', val)
.then(() => preferences.flush()) // 刷到磁盘
.catch(reason =>{}) // 处理异常
// 删除数据
preferences.delete('key')
.then(() => {}).catch(reason => {})
// 查询数据
preferences.get('key', 'defaultValue')
.then(value => console.log('查询成功'))
.catch(reason => console.log('查询失败'))
说明:
- Key为string类型,要求非空且长度不超过80字节
- Value可以是string、number、boolean及以上类型数组,大小不超过8192字节
- 数据量建议不超过一万条
使用示例:
import preferences from '@ohos.data.preferences'; class PreferencesUtil { // 存储preferences prefs: Map<string, preferences.Preferences> = new Map() // 初始化preferences async initPreferences(context, name: string) { try { const pref = await preferences.getPreferences(context, name) this.prefs.set(name, pref) console.log('testTag', `preferences-${name} 初始化成功`) } catch (e) { console.log('testTag', `preferences-${name} 初始化失败:`, JSON.stringify(e)) } } // 写入数据 async putPreferences(name: string, key: string, value: preferences.ValueType) { if (!this.prefs.has(name)) { console.log(`testTag`, `preferences-${name} 不存在`) return false } try { const pref = this.prefs.get(name) // 写入数据 await pref.put(key, value) // 刷入磁盘 await pref.flush() console.log('testTag', `preferences-${name} 数据写入成功`) } catch (e) { console.log('testTag', `preferences-${name} 数据写入失败:`, JSON.stringify(e)) } } // 查询数据 async getPreferences(name: string, key: string, defaultValue: preferences.ValueType) { if (!this.prefs.has(name)) { console.log(`testTag`, `preferences-${name} 不存在`) return false } try { const pref = this.prefs.get(name) // 查询数据 const value = await pref.get(key, defaultValue) console.log('testTag', `preferences-${name} 数据查询成功:`, value) return value } catch (e) { console.log('testTag', `preferences-${name} 数据查询失败:`, JSON.stringify(e)) return '' } } // 删除数据 async delPreferences(name: string, key:string) { if (!this.prefs.has(name)) { console.log(`testTag`, `preferences-${name} 不存在`) return false } try { const pref = this.prefs.get(name) // 查询数据 await pref.delete(key) console.log('testTag', `preferences-${name} 数据删除成功`) } catch (e) { console.log('testTag', `preferences-${name} 数据删除失败:`, JSON.stringify(e)) return '' } } // 删除所有 async delAllPreferences(name: string | Array<string>, key:string) { let nameList = [] if (name.length) { // 数组 nameList = [...name] } else { nameList = [name] } const hasTag = nameList.filter(item => this.prefs.has(item)) if (!hasTag || (hasTag && hasTag.length === 0)) { console.log(`testTag`, `preferences-${name} 不存在`) return false } try { nameList.forEach((item, index) => { const pref = this.prefs.get(item) pref.clear() console.log('testTag', `preferences-${index}_${name} 全部删除成功`) }) } catch (e) { console.log('testTag', `preferences-${nameList} 删除失败:`, JSON.stringify(e)) return '' } } } const putils = new PreferencesUtil() export default putils as PreferencesUtil
在入口文件EntryAbility.ts下添加如下代码
async onCreate(want, launchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
// 全局初始化
await PreferencesUtil.initPreferences(this.context, 'MyAppPreferences');
// 如果有多个可以继续初始化
// await PreferencesUtil.initPreferences(this.context, 'MyOrderPreferences');
}
//Index组件(父组件) import PreferencesUtil from '../utils/PreferencesUtil' @Entry @Component struct Index { @State fontSize: number = 16 build() { Row() { Column() { DemoBuilder({ fontSize: this.fontSize }) Row() { Button("字体20") .width(100) .height(40) .fontSize(18) .fontColor(Color.White) .backgroundColor(Color.Blue) .margin(10) .onClick(async () => { this.fontSize = 22 await PreferencesUtil.putPreferences("MyAppPreferences", "fontSize", 22) console.log('添加成功') }) Button("字体30") .width(100) .height(40) .fontSize(18) .fontColor(Color.White) .backgroundColor(Color.Blue) .margin(10) .onClick(async () => { this.fontSize = 30 await PreferencesUtil.putPreferences("MyAppPreferences", "fontSize", 30) console.log('添加成功30') }) }.margin({top: 30}) } } .height('100%') } } // 子组件 import PreferencesUtil from '../../utils/PreferencesUtil' @Component export struct DemoBuilder { @Prop fontSize: number // 自定义构建函数 @Builder showRepeatCode() { Text("重复UI调用") .fontColor(Color.Red) .fontSize(this.fontSize) } async aboutToAppear() { this.fontSize = await PreferencesUtil.getPreferences("MyAppPreferences","fontSize",16) as number } build() { Column() { this.showRepeatCode() Text("测试字体大小") .fontColor(Color.Blue) .fontSize(this.fontSize) .margin({top: 30}) // myGlobalBuilder() } } }
关系型数据库(RDB)是基于SQLite组件提供的本地数据库,用于管理应用中的结构化数据。例如:记账本、备忘录
步骤1:初始化数据库
import relationalStore from '@ohos.data.relationalStore'
// rdb配置 const config = { name: 'MyApplication.db', // 数据库文件名 securityLevel: relationalStore.SecurityLevel.S1 // 数据库安全级别 } // 初始化表的SQL const sql = `CREATE TABLE IF NOT EXISTS TASK ( ID INTEGER PRIMARY KEY, NAME TEXT NOT NULL, FINISHED bit )` // 获取rdb relationalStore.getRdbStore(this.context, config, (err, rdbStore) => { // 执行sql,后续的所有增删改查都是使用rdbStore对象 rdbStore.executeSql(sql) })
步骤2:增、删、改、查数据
// 准备数据
const task = { id: 1, name: '测试1', finished: false }
// 新增
this.rdbStore.insert(this.tableName, task)
// 要更新的数据
const task = { finished: true }
// 查询条件,RdbPredicates就是条件谓词
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('ID', id)
// 执行更新
this.rdbStore.update(task, predicates)
// 查询条件
const predicates = new relationalStore.RdbPredicates(this.tableName)
predicates.equalTo('ID', id)
// 执行删除
this.rbdStore.delete(predicates)
// 查询条件 const predicates = new relationalStore.RdbPredicates(this.tableName) // 执行查询 ['ID', 'NAME', 'FINISHED'] => 需要查询的字段 const result = await this.rdbStore.query(predicates, ['ID', 'NAME', 'FINISHED']) // 解析结果 (接触过数据库都知道,查询数据一般返回的是一个结果集) // 准备数据保存结果 let tasks: any[] = [] // 循环遍历结果集,判断是否遍历到最后一行 while(!result.isAtLastRow) { // 指针移动到下一行数据 result.goToNextRow() // 根据字段名获取字段index,从而获取字段值 const id = result.getLong(result.getColumnIndex("ID")) const name = result.getString(result.getColumnIndex("NAME")) tasks.push({id, name}) }
关系数据库使用示例:
// 创建TaskModel.ets /** * 这里为什么创建.ets文件? * 原因:如果是创建ts文件,那么就不能使用ArkTs的状态管理,所需要创建为.ets文件 * 另外,项目初始化时,如果入口文件EntryAbility文件如果是.ts,则需要改为.ets文件** ,因为.ts文件不能导入.ets文件 */ import relationalStore from '@ohos.data.relationalStore'; /** * 说明:如果是跨组件使用TaskModel,那么需要加上@Observed进行属性观察, * 本例子所有代码都在当前组件写了,所以就不添加@Observed了 */ // @Observed class TaskModel { // 存储rdbStore private rdbStore: relationalStore.RdbStore // 表名 private tableName: string = 'TASK' // 这里写死了,后续优化可以抽取为参数传值 /** * 初始化数据表 * @param context */ async initTaskModel(context) { // rdb 配置 const config = { name: 'MyApplication.db', securityLevel: relationalStore.SecurityLevel.S1 } // 初始化数据表 const sql = `CREATE TABLE IF NOT EXISTS TASK ( ID INTEGER PRIMARY KEY, NAME TEXT NOT NULL, FINISHED bit )` try { // 获取rdb const rdbStore = await relationalStore.getRdbStore(context, config) // 执行SQL rdbStore.executeSql(sql) this.rdbStore = rdbStore } catch (e) { console.log('testTag', '获取rdbStore失败', JSON.stringify(e)) } } /** * 查询task列表数据 * 注:这里后续有需要可以抽取成公用方法,有点麻烦,先简单写,嘿嘿 */ async getTaskList() { // 查询条件 const predicates = new relationalStore.RdbPredicates(this.tableName) // 执行查询 const result = await this.rdbStore.query(predicates, ['ID', 'NAME', 'FINISHED']) // 解析结果 (接触过数据库都知道,查询数据一般返回的是一个结果集) // 准备数据保存结果 let tasks: any[] = [] // 循环遍历结果集,判断是否遍历到最后一行 while(!result.isAtLastRow) { // 指针移动到下一行数据 result.goToNextRow() // 根据字段名获取字段index,从而获取字段值 const id = result.getLong(result.getColumnIndex("ID")) const name = result.getString(result.getColumnIndex("NAME")) const finished = result.getLong(result.getColumnIndex("FINISHED")) tasks.push({id, name, finished}) } console.log('testTag', '数据查询成功', JSON.stringify(tasks)) return tasks } /** * 删除任务 * @param id * @returns */ delTask(id: number): Promise<number> { // 查询条件 const predicates = new relationalStore.RdbPredicates(this.tableName) predicates.equalTo('ID', id) // 执行删除 return this.rdbStore.delete(predicates) } /** * 更新任务列表 * @param id * @param finished * @returns */ updateTask(id: number, finished: boolean): Promise<number> { // 更新的数据 const data = { finished } // 查询条件 const predicates = new relationalStore.RdbPredicates(this.tableName) predicates.equalTo('ID', id) // 执行删除 return this.rdbStore.update(data, predicates) } /** * 添加任务 * @param name * @param finished * @returns */ addTask(name: string, finished: boolean): Promise<number> { // 新增 return this.rdbStore.insert(this.tableName, { name, finished }) } } const model = new TaskModel() export default model as TaskModel
初始化TaskModel
// EntryAbility.ets文件加入如下代码
async onCreate(want, launchParam) {
...
// 初始化数据表
await TaskModel.initTaskModel(this.context)
}
使用TaskModel
import TaskModel from '../model/TaskModel' @Entry @Component struct Index { @State taskName: string = '' @State taskList: any[] = [] async aboutToAppear() { this.handleRefreshList() } async handleRefreshList() { this.taskList = await TaskModel.getTaskList() } @Builder delButton($$: { id: number }) { Button('删除') .fontSize(18) .fontColor(Color.White) .backgroundColor(Color.Red) .margin({ left: 15 }) .onClick(async () => { await TaskModel.delTask($$.id) this.handleRefreshList() }) } build() { Row() { Column() { Row() { TextInput({ placeholder: '请输入任务名称', text: this.taskName }) .fontSize(20) .width(300) .onChange(val => { this.taskName = val }) Button("添加") .height(40) .fontSize(20) .fontColor(Color.White) .backgroundColor(Color.Blue) .layoutWeight(1) .margin({left: 10}) .onClick(async () => { await TaskModel.addTask(this.taskName, false) this.handleRefreshList() // 清空输入框 this.taskName = '' }) }.margin({bottom: 20}) .justifyContent(FlexAlign.SpaceBetween) // 渲染列表 List({ space: 10 }) { ForEach(this.taskList, (item, index) => { ListItem() { Row() { Text(item.name) .fontSize(24) .fontColor("#ff6602") .fontWeight(FontWeight.Bold) Checkbox() .select(!!item.finished) .selectedColor("#ff6602") .onChange(async (value) => { await TaskModel.updateTask(item.id, value) // 这里可以重新请求一次查询数据,也可以不加 }) } .width("90%") .borderWidth(1) .borderColor("#dddddd") .padding(10) .justifyContent(FlexAlign.SpaceBetween) } .swipeAction({ end: this.delButton({ id: item.id }) }) }) } .alignListItem(ListItemAlign.Center) } .justifyContent(FlexAlign.Start) .height("100%") } .height('100%') } }
效果图:
本文主要是对HarmonyOS的HTTP网络请求做了简单的了解,以及对数据持久化的使用示例,如有不足之处,请指正,谢谢查阅!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。