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

HarmonyOS开发 - 本地持久化之实现LocalStorage支持多实例

        用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。

        在上一篇中,对Preference实例进行封装,实现LocalStorage相关功能,并在基础上再增加对json对象数据存储能力,还实现了数据缓存具有时效性等功能。地址:HarmonyOS开发 - 本地持久化之实现LocalStorage实例-CSDN博客

        不过LocalStorage示例为单例模式,当在多个Ability或多module情况下,不希望所有数据都存储在一个Preferences实例中,这就需要LocalStorage有支持多实例的能力。

一、Ability和Module

        在HarmonyOS开发中,Ability是应用或服务所具备的能力的抽象,它可以响应用户的操作,与用户进行交互。一个Module可以包含一个或多个Ability。HarmonyOS提供了两种应用模式:FA(Feature Ability)模型和Stage模型。

        FA模型从API7开始支持,但已不再是主推的模型。而Stage模型从API 9开始新增,是目前主推且会长期演进的模型。在Stage模型中,Ability分为两种组件类型:

  1. UIAbility组件:包含UI界面,提供展示UI的能力,主要用于和用户交互。
  2. ExtensionAbility组件:提供特定场景的扩展能力,满足更多的使用场景。当前仅OpenHarmony工程支持使用ExtensionAbility组件。

        在HarmonyOS中,应用可以设计为包含多个Ability或者多个module,这取决于应用的复杂性和模块化需求。

1.1 多个Ability

        一个应用可以包含多个Ability,每个Ability代表应用的一种能力。Ability分为Feature Ability(FA)和Particle Ability(PA)两种类型。FA是有UI界面的能力,用于与用户交互,例如一个页面或一个服务。PA是后台运行的能力,可以是Service Ability或Data Ability,用于提供后台任务或数据访问的能力。在Stage模型中,Ability进一步细分为UIAbility组件和ExtensionAbility组件,其中UIAbility组件包含UI界面,而ExtensionAbility组件提供特定场景的扩展能力。

多个Ability

1.2 多个module

        在HarmonyOS中,应用可以被分解为多个功能模块,每个模块负责执行特定的功能。这些模块可以是Shared Library、Static Library或Visual Library。Shared Library是HSP(Harmony Shared Package)动态共享包,Static Library是HAR(Harmony Archive)静态共享包。模块化设计提高了代码的可理解性和可复用性,使应用的扩展和维护变得更为简便,同时降低了系统各部分之间的耦合度。

多个Module

1.3 二者选择

        对于多应用的情况,你可以选择使用多个Ability或多个module,这取决于你的应用架构和业务需求。如果应用功能较为独立,且需要在不同应用间共享,那么可能更适合使用多个module。每个module可以包含一个或多个Ability,这样可以在不同的module之间实现功能的解耦和复用。如果应用的功能较为集中,且主要通过不同的页面或服务来提供用户交互,那么使用多个Ability可能更为合适。

        在实际开发中,你可以根据应用的特点和需求,灵活选择使用多个Ability或多个module,或者将两者结合起来,以实现最佳的应用架构和性能。

二、LocalStorage升级

        在前一篇(地址:HarmonyOS开发 - 本地持久化之实现LocalStorage实例-CSDN博客)中封装的LocalStorage类,创建Preferences实例时指定的实例名称用的是Module模块名称(context.abilityInfo.moduleName);在了解Ability和Module关系后,决定将实例名称更新为Ability名称(context.abilityInfo.name)。

2.1 LocalStorage类

        这里将LocalStorageObj文件复制一份,在新文件中增加多实例功能,同时applicationability和Productability的Ability界面和pages页面中,引入的模块地址也需要同步修改为:"../utils/LocalStorageMulti"。

        这里只需要在之前LocalStorage类基础上,增加一个静态变量用于存储键值对的实例,和一个创建实例的静态函数即可。

  • 键值对的存储器(multiPreferences变量):利用Map对象的特性,键(key)为string类型,用于存储ability名称;值(value)为LocalStorge类型,用于存储类的实例对象。
  • 创建实例函数(multiInstance()函数):通过Map对象中has()方法判断该对应的ability界面实例是否存在,不存在则创建并返回创建的LocalStorage实例;若存在则直接返回该键对应的LocalStorage实例。

        示例代码如下:

import common from '@ohos.app.ability.common'
import preferences from '@ohos.data.preferences'
import { isJsonObject } from './utils'// 定义存储值类型
type valueType = string | number | boolean
// 定义json对象存储类型
type dataType = { value: valueType | object, expire: number }/*** 定义LocalStorage类*/
export class LocalStorage {private preference: preferences.Preferences // 用户首选项实例对象// 定义多Preferences实例 存储变量字段private static multiPreferences: Map<string, LocalStorage> = new Map()/*** 创建多实例* @param context*/static multiInstance(context?: common.UIAbilityContext): LocalStorage {const name = context.abilityInfo.name// 如果存在该实例,则直接返回if(LocalStorage.multiPreferences.has(name)) {console.log('testTag context.abilityInfo.name update', name)return LocalStorage.multiPreferences.get(name)}// 如果不存在,则创建实例else {console.log('testTag context.abilityInfo.name create', name)const instance = new LocalStorage()     // 实例LocalStorage对象instance.initial(context)               // 初始化Preferences实例// 存储LocalStorage对象LocalStorage.multiPreferences.set(name, instance)// 返回实例对象return instance}}// 定义初始化函数initial(context: common.UIAbilityContext): void {// 这里将UIAbility中应用上下文的name作用为实例名称,即该项目的ApplicationAbility或ProductAbilitypreferences.getPreferences(context, context.abilityInfo.name).then(preference => {this.preference = preferenceconsole.log('testTag', 'success~')}).catch(e => {console.log('testTag error', e)})}// 略...
}

        注意:initial()函数中须将之前context.abilityinfo.moduleName修改为context.abilityinfo.name。

2.2 Ability中初始化实例

        在两个Ability中,引入LocalStorage模块,并初始化实例。由于multiinstance()为静态函数,通过LocalStorage类直接调用即可。

applicationability组件:

Productability组件:

2.3 page页面中获取实例

        在HarmonyOS中,aboutToAppear是页面生命周期中的一个关键回调,它在创建自定义组件的新实例后,在执行其build()函数之前执行。这个回调允许开发者在组件实例创建后改变状态变量,并这些更改将在后续执行build()函数中生效。

        aboutToAppear的使用场景包括但不限于:

  1. 初始化页面状态变量
  2. 执行数据绑定和事件监听的设置
  3. 执行与页面显示相关的动画或过渡效果

        总的来说,aboutToAppear是HarmonyOS中管理页面生命周期的一个重要工具,它提供了页面显示前执行初始化操作的能力。而且多应用环境中,合理地使用多个Ability或module可以有效地组织和管理复杂的应用结构。

        因此,我们将通过aboutToAppear来获取本Ability界面中的LocalStorage实例对象。

applicationability界面下的pages/index.ets示例代码如下:

import { LocalStorage } from '../utils/LocalStorageMulti'
import common from '@ohos.app.ability.common'
import Want from '@ohos.app.ability.Want'@Entry
@Component
struct Index {@State message: string = ''private localStorage: LocalStorage    // 定义变量,接收本Ability界面下的LocalStorage实例对象aboutToAppear(){// 获取当前上下文的LocalStorage实例对象this.localStorage = LocalStorage.multiInstance(getContext(this) as common.UIAbilityContext)}// 重置内容renderMsg(message: string | number | boolean){this.message = message.toString()}build() {Row() {Column() {Row(){Text(this.message || '-').fontSize(30).fontWeight(FontWeight.Bold)}.width('100%').height('150vp')Row(){// 添加相关操作按钮Button('添加').onClick(() => {const testData = { name: 'Tom', age: 18 };const expireDate = new Date()// 设置为24小时后失效expireDate.setHours(expireDate.getHours() + 24)// 存储数据this.localStorage.put('indexValue', testData, expireDate)this.renderMsg('add:' + JSON.stringify(testData))console.log('testTag add', testData)})Button('读取').onClick(() => {this.localStorage.getValue('indexValue').then(value => {this.renderMsg('get:' +  (null !== value ? JSON.stringify(value) : value))console.log('testTag get', value)}).catch(err => {console.log('testTag error', err)})})Button('删除').onClick(async () => {this.localStorage.remove('indexValue')const value = await this.localStorage.getValue('indexValue')this.renderMsg('delete:' + value)console.log('testTag delete', value)})Button('跳转新页面').onClick(() => {const context = getContext(this) as common.UIAbilityContextconst want: Want = {bundleName: 'com.example.myapplication',abilityName: 'ProductAbility',moduleName: 'application',parameters: {instanceKey: 'product'}}context.startAbility(want)})}.width('100%').justifyContent(FlexAlign.Center)}.width('100%')}.height('100%').alignItems(VerticalAlign.Top)}
}

        对LocalStorage类进行多实例改造后,数据的存储能力依然能正常执行。如下图:

Productability界面下的pages/indexProduct.ets示例代码如下:

import { LocalStorage } from '../utils/LocalStorageMulti'
import common from '@ohos.app.ability.common'
let index = 0@Entry
@Component
struct Index {@State message: string = ''private localStorage: LocalStorage // 定义变量,接收本Ability界面下的LocalStorage实例对象aboutToAppear(){// 获取当前上下文的LocalStorage实例对象this.localStorage = LocalStorage.multiInstance(getContext(this) as common.UIAbilityContext)}// 重置内容renderMsg(message: string | number | boolean){this.message = message.toString()}build() {Row() {Column() {Row(){Text(this.message || '-').fontSize(30).fontWeight(FontWeight.Bold)}.width('100%').height('150vp')Row(){// 添加相关操作按钮Button('添加').onClick(() => {this.localStorage.put('indexValue', ++index)this.renderMsg('add:' + index)console.log('testTag add', index)})Button('读取').onClick(() => {this.localStorage.getValue('indexValue').then(value => {this.renderMsg('get:' +  (null !== value ? JSON.stringify(value) : value))console.log('testTag get', value)}).catch(err => {console.log('testTag error', err)})})Button('删除').onClick(async () => {this.localStorage.remove('indexValue')const value = await this.localStorage.getValue('indexValue')this.renderMsg('delete:' + value)console.log('testTag delete', value)})}.width('100%').justifyContent(FlexAlign.Center)}.width('100%')}.height('100%').alignItems(VerticalAlign.Top)}
}

        在Applicationability界面点击添加和读取后,再跳转到Productability界面,点击“读取”按钮,看是否能获取到Applicationability界面的indexValue键对应的值。如下图,显示是获取不到的,虽然两则都存的键为indexValue,但都存储在不能的Preferences实例中。

        在Productability界面,点击添加后,再读取。结果如下图:

2.4 multiInstance()函数

        在LocalStorage实现多实例功能时,对multiInstance()函数的设计,是可以无须先初始化实例,直接在页面中aboutToAppear回调函数并获取当前Ability界面实例。

        此时我们将两个Ability中的onCreate()函数,执行的LocalStorage.multiInstance()删除掉,只在page页面直接获取,再看下结果。

        如上图,初始化实例调用的函数注释掉后,结果是怎样的。

        如上图,此时只执行了页面中的multiInstance()函数,但操作结果依然是正常的;不过注意的是,在aboutToAppear回调函数中只是初始化LocalStorage实例是没问题的,但是直接调用实例对象的put()、get()、remove()、clear()等函数,可能会报错,显示preference实例不在存,这是因为initial()函数中是通过Promise异步回调获取的preference实例的。

        所以,是否需要在ability中执行初始化,还是在页面中执行初始化,根据实现需求而定。

2.5 总结

        在多应用的环境中,你可能会使用多个Ability或多个module来组织你的应用。Ability允许你创建多个具有不同功能的页面或服务,而module则允许你将应用分解为多个功能模块,每个模块可以包含一个或多个Ability。这样的设计有助于提高代码的可维护性和可扩展性。

        该篇是为上一篇(HarmonyOS开发 - 本地持久化之实现LocalStorage实例-CSDN博客)的补充内容,希望对大家有所帮助。

相关文章:

HarmonyOS开发 - 本地持久化之实现LocalStorage支持多实例

用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。数据存储形式为键值对&#xff0c;键的类型为字符串型&#xff0c;值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。 在上一篇中&…...

【已解决,含泪总结】非root权限在服务器Ubuntu18.04上配置python和torch环境,代码最终成功训练(二)

配置torch环境 pip升级 因为一些包安装不成功可能和pip版本有关&#xff0c;所以先升级pip 吸取之前python有多个版本的经验&#xff0c;所以我指定了Python版本的pip进行升级 就是python3.8版本&#xff1a; /home/某某/Python3.8/bin/python3.8 &#xff08;要换成你实际的…...

Flutter鸿蒙next 刷新机制的高级使用【衍生详解】

✅近期推荐&#xff1a;求职神器 https://bbs.csdn.net/topics/619384540 &#x1f525;欢迎大家订阅系列专栏&#xff1a;flutter_鸿蒙next &#x1f4ac;淼学派语录&#xff1a;只有不断的否认自己和肯定自己&#xff0c;才能走出弯曲不平的泥泞路&#xff0c;因为平坦的大路…...

c/c++--静态变量和静态函数(static)

目录 1 c静态函数和静态变量 1.1 C静态成员函数&#xff1a; 1.1.1定义与基本语法 1.1.2 不依赖于实例 1.1.3 访问限制 1.1.4共享数据 1.1.5 作用域与命名 1.1.6 工厂函数和工厂方法&#xff08;常用途&#xff09; ​​​1.2 c静态函数&#xff08;) 1.3c静态变量 …...

Windows系统启动MongoDB报错无法连接服务器

文章目录 发现问题解决办法 发现问题 1&#xff09;、先是发现执行 mongo 命令&#xff0c;启动报错&#xff1a; error: MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017&#xff1b; 2&#xff09;、再检查 MongoDB 进程 tasklist | findstr mongo 发现没有进程&a…...

Linux的makefile与进度条小程序实践

makefile make命令主要功能使用方法常用选项 makefile文件基本结构使用案例变量定义内置变量(即系统定义的确定变量)伪目标模式规则条件语句注释makefile中的常用函数 进度条小程序创建文件编辑.h文件编辑.c文件创建main函数makefile文件执行效果 make命令 在linux中&#xff…...

latex写作基础

参考&#xff1a;https://www.bilibili.com/video/BV1ku4y1X7Rz 在线latex&#xff1a;https://cn.overleaf.com/ tex文件基本结构 \documentclass{article} % 文档类型&#xff0c;&#xff05;是注释\usepackage{graphicx} % 导入各种包&#xff0c;这里是graphicx包\titl…...

Chromium HTML5 新的 Input 类型email对应c++

一、Input 类型: email email 类型用于应该包含 e-mail 地址的输入域。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php"…...

嵌入式Linux的AXI平台(platform)驱动教程

本文以JFMQL100的Linux系统的AXI接口的平台驱动为例&#xff0c;介绍嵌入式Linux的平台驱动编写、测试软件编写以及验证方式。本文的方法适用于任意嵌入式芯片Linux的物理地址映射的平台&#xff08;platform&#xff09;驱动的编写、测试与应用。 本文中AXI的开始地址为0x8000…...

什么是Java策略模式?与Spring的完美结合

文章目录 什么是策略模式&#xff1f;策略模式的组成部分&#xff1a; 策略模式的示例在Spring中的妙用1. 使用Spring配置2. 在上下文中选择策略3. 动态切换策略 总结推荐阅读文章 在软件设计中&#xff0c;策略模式是一种非常常见的设计模式&#xff0c;它能够让算法的变化独立…...

[Go实战]:HTTP请求转发

前言 在Web应用开发中&#xff0c;请求转发是一项核心且常见的功能&#xff0c;用于负载均衡、服务拆分、路由重定向和业务逻辑处理。通过在Go语言中封装一个通用的HTTP请求转发方法&#xff0c;我们可以简化代码结构&#xff0c;提升可读性、可维护性和可扩展性。本文将探讨如…...

【C++单调栈 贡献法】907. 子数组的最小值之和|1975

本文涉及的基础知识点 C单调栈 LeetCode907. 子数组的最小值之和 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr 的每个&#xff08;连续&#xff09;子数组。 由于答案可能很大&#xff0c;因此 返回答案模 109 7 。 示例 1&#x…...

极狐GitLab 17.5 发布 20+ 与 DevSecOps 相关的功能【二】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

Django 5 增删改查 小练习

1. 用命令创建目录和框架 django-admin startproject myapp cd myapp py manage.py startapp app md templates md static md media 2. Ai 生成代码 一、app/models.py from django.db import modelsclass Product(models.Model):name models.CharField(max_length255, verb…...

【STM32 Blue Pill编程实例】-I2C主从机通信(中断、DMA)

I2C主从机通信(中断、DMA) 文章目录 I2C主从机通信(中断、DMA)1、STM32的I2C介绍2、I2C模式3、STM32 I2C 数据包错误检查4、STM32 I2C 错误情况5、STM32 I2C中断6、STM32 I2C 主发送和接收(Tx 和 RX)6.1 I2C 轮询模式6.2 I2C 中断模式6.3 I2C DMA 模式6.4 STM32 I2C 设备…...

基于SSM+小程序的旅游社交登录管理系统(旅游4)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 ​ 本旅游社交小程序功能有管理员和用户。管理员有个人中心&#xff0c;用户管理&#xff0c;每日签到管理&#xff0c;景点推荐管理&#xff0c;景点分类管理&#xff0c;防疫查询管理&a…...

高级java每日一道面试题-2024年10月24日-JVM篇-说一下JVM有哪些垃圾回收器?

如果有遗漏,评论区告诉我进行补充 面试官: 说一下JVM有哪些垃圾回收器? 我回答: 1. Serial收集器 特点&#xff1a;Serial收集器是最古老、最稳定的收集器&#xff0c;它使用单个线程进行垃圾收集工作。在进行垃圾回收时&#xff0c;它会暂停所有用户线程&#xff0c;即St…...

Java-内部类

个人主页 学习内部类&#xff08;Inner Class&#xff09;是Java编程中一项重要且强大的特性&#xff0c;它允许你在一个类的内部定义另一个类。内部类提供了一种将逻辑上相关的类组织在一起的方式&#xff0c;增加了代码的封装性和可读性。接下来带领大家进入內部类的学习。 …...

flutter集成极光推送

一、简述 极光推送&#xff0c;英文简称 JPush&#xff0c;免费的第三方消息推送服务&#xff0c;官方也推出众多平台的SDK以及插件。 参考链接 名称地址客户端集成插件客户端集成插件 - 极光文档 二、操作步骤 2.1 添加插件 flutter项目中集成官方提供的 极光推送flutte…...

D. Skipping 【 Codeforces Round 980 (Div. 2)】

D. Skipping 思路: 注意到最佳策略是先往右跳转到某处&#xff0c;然后按顺序从右往左把没有遇到过的题目全部提交。 将从 i i i跳转到 b [ i ] b[i] b[i]视为通过边权(代价)为 a [ i ] a[i] a[i]的路径&#xff0c;而向左的路径边权都是 0 0 0&#xff1b;目的是找到到从出发…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...