应用数据持久化案例
使用不同 模块 完成首选项、键值型、关系型持久化。配套源码点击此处查看GitCode仓库,记得给仓库一个star。
1 入口模块 module 拉起指定其他模块
1.1 新建多个模块
分别命名为:preferences、kvStore、relationalStore。

1.2 在入口模块中拉起其他模块
设计entry模块中src/main/ets/pages/Index.ets的UI效果。三个按钮,点击事件中使用UIAbilityContext对象的startAbility方法传入Want对象拉起指定Ability。
import { Want } from '@kit.AbilityKit'
import common from '@ohos.app.ability.common'
@Entry
@Component
struct Index {
context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext
//通用的跳转指定UIAbility方法
startTargetAbility(moduleName: string, abilityName: string, info?: string) {
// console.log(`dxin => bundleName:${this.context.applicationInfo.name}`)
this.context.startAbility({
deviceId: '', // 本设备
bundleName: this.context.applicationInfo.name, //也可动态获取
moduleName: moduleName, // 目标 模块名称
abilityName: abilityName, // 该模块下可能有多个 ability
parameters: {
info: info// 参数可以省略
}
})
}
build() {
Column({ space: 30 }) {
Text('三种数据持久化方案').fontSize(30)
Button('用户首选项').fontSize(22).buttonStyle(ButtonStyleMode.TEXTUAL)
.onClick(() => {
this.startTargetAbility('preferences', 'PreferencesAbility', "dxin-preferences")
})
Button('键值型数据库').fontSize(22).buttonStyle(ButtonStyleMode.TEXTUAL)
.onClick(() => {
this.startTargetAbility('kvStore', 'KvStoreAbility')
})
Button('关系型数据库').fontSize(22).buttonStyle(ButtonStyleMode.TEXTUAL)
.onClick(() => {
this.startTargetAbility('relationalStore', 'RelationalStoreAbility')
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.backgroundColor($r('app.color.theme_color'))
}
}
1.3 运行项目测试拉起效果:
如果你正在尝试跳转到其他模块(如从 entry 跳转到 my_module),需要在 DevEco Studio 中进行额外配置,否则目标模块不会被安装。
-
点击 Run > Edit Configurations。
-
找到你的运行配置。
-
勾选 Deploy Multi Hap ~Packages。

1.4 美化各模块icon和label
在每个模块中添加icon图标,修改label名程,修改module.json5文件
![]()
2 preferences用户数首选项
2.1 获取Entry中拉起时传递的参数
PreferencesAbility中获取参数,如果获取不到,给出默认值'首选项'。为了在页面中展示该数据,使用**应用全局UI状态存储AppStorageV2。因为AppStorageV2只支持class**类型,否则会抛出运行时报错,从API version 23开始,将返回错误码140103。所以需要设计一个ParamType类。
PreferencesAbility.ets
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 获取主模块传递过来的参数 存储到AppStorageV2中方便页面使用
let abilityWant = want
let info = abilityWant?.parameters?.info.toString() || '首选项'
AppStorageV2.connect(ParamType, 'info', () => new ParamType(info))
}
src/main/ets/model/ParamType.ets
export default class ParamType{
message:string
constructor(message: string) {
this.message = message
}
}
2.2 在Index中展示获取的参数。
切记1.3步骤中的配置。否则你会发现拉起失败。
import ParamType from '../model/ParamType'
import { AppStorageV2 } from '@kit.ArkUI'
@Entry
@Component
struct Index {
info: ParamType = AppStorageV2.connect(ParamType, 'info', () => new ParamType('info is undefined'))!
build() {
Column({ space: 30 }) {
Text(this.info.message).fontColor("#fff50909").fontSize(40)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
2.3 主题名称切换效果
准备数组THEME_NAMES存储三种主题 ['default','grey','simple']。使用状态变量themeModel取出数组中的默认数据。在布局中,点击bindMenu的action事件进行主题名称的切换。

如果仅仅是为了完成主题名称的切换,直接使用状态变量字符串即可,但是为了配合后续的主题内容(图片+名程),所以需要设计为数组,方便以下标对应主题内容。
import ParamType from '../model/ParamType'
import { AppStorageV2 } from '@kit.ArkUI'
@Entry
@ComponentV2
struct Index {
info: ParamType = AppStorageV2.connect(ParamType, 'info', () => new ParamType('info is undefined'))!
// 准备一个数组存储不同主题的名程。
THEME_NAMES:string[] = ['default','grey','simple']
// 默认一个主题 从数组中取出
@Local currentThemeName: string = this.THEME_NAMES[0]
// 修改所选主题
changeTheme(index: number) {
// 主题名称
this.currentThemeName = this.THEME_NAMES[0]
}
build() {
Column({ space: 30 }) {
Text(this.info.message).fontColor("#fff50909").fontSize(40)
Row() {
Text("主题:" + this.currentThemeName)
.fontSize(20)
.layoutWeight(5)
.padding({ left: 10 })
.fontColor(Color.White)
.fontWeight(FontWeight.Bold)
Image($r('app.media.change'))
.key('changeBtn')
.id('changeBtn')
.height(30)
.layoutWeight(1)
.objectFit(ImageFit.ScaleDown)
.bindMenu([
{
value: 'default', action: () => {
this.changeTheme(0)
}
},
{
value: 'grey',
action: () => {
this.changeTheme(1)
}
},
{
value: 'simple',
action: () => {
this.changeTheme(2)
}
}
])
}
.width('100%')
.height(50)
.backgroundColor('#0D9FFB')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
2.4 主题内容切换

准备对应三种主题数据数组。该数组中存放的是主题内容的图标和名称,数据提前存放到src/main/resources/rawfile。所以先设计主题模型ThemeModel
src/main/ets/model/ThemeModel.ets
export interface ThemeModel {
image: string | Resource
name: string;
}