鴻蒙原生應用開發——分散式資料物件
01、什麼是分散式資料物件
在可信組網環境下,多個相互組網認證的裝置將各自建立的物件加入同一個 sessionId,使得加入的多個資料物件之間可以同步資料,也就是說,當某一資料物件屬性發生變更時,其他資料物件會檢測到這一變更,同時將自身屬性更新。此時,該 sessionId 下的所有資料物件屬性相同,這樣的資料物件稱之為分散式資料物件。此外,分散式資料物件可以被動退出 sessionId,當分散式資料物件退出 sessionId 後,該物件將檢測不到其他物件的變更。
02、分散式資料物件能力
1、 分散式資料物件建立
2、 分散式資料物件查詢
3、 分散式資料物件修改
4、 分散式資料物件刪除
5、 分散式資料物件儲存
6、 分散式資料物件訂閱(資料變更,上下線)
7、分散式資料物件加入、退出分散式組網
03、前提準備
1、 開發工具:DevEco Studio 3.1.0.501
2、API:9
3、 SDK 版本:3.2.12.5
04、建立一個新的專案
新建專案,選擇 API9 版本,stage 模型。
05、許可權申請
1、 使用到的許可權
○ ohos.permission.DISTRIBUTED_DATASYNC
○ 允許不同裝置間的資料交換
○ 許可權級別:normal
○ 授權方式:user_grant
○ ACL 使能:TRUE
2、配置檔案申明
首先,在專案的模組級目錄下找到並開啟 module.json5 檔案,如下圖:
在 module 下的物件裡新增如下申明:
此時,配置檔案中的許可權申明就完成了,但是,此時我們還不能獲得這些許可權。由於 ohos.permission.DISTRIBUTED_DATASYNC 許可權是 ACL 使能為 TRUE 的許可權,需要在簽名工具檔案中說明一下。
如何找到對應的簽名工具檔案呢?我們在安裝 DevEco Studio 的時候是下載好了 OpenHarmony 的 SDK 的,此時在 OpenHarmony 資料夾中,開啟 “Sdk\OpenHarmony SDK 版本\toolchains\lib” 該路徑,此時在 lib 資料夾中,我們們可以找到兩個 json 檔案,分別為 UnsgnedDebugProfileTemplate.json 和 UnsgnedReleasedProfileTemplate.json,點選並開啟這兩個檔案,新增如下許可權:
3、許可權申請編碼
在申請 ohos.permission.DISTRIBUTED_DATASYNC 許可權時,其文件中將其標註為使用者手動授權的許可權,此時需要我們動態申請許可權,在專案中,我們新建一個 ets 檔案,我這裡取名為 RequestPermission.ets。
首先,匯入以下包:
import abilityAccessCtrl, {
Permissions }
from
'@ohos.abilityAccessCtrl';
import bundleManager
from
'@ohos.bundle.bundleManager';
import common
from
'@ohos.app.ability.common';
獲取訪問控制模組物件例項:
let atManager = abilityAccessCtrl.
createAtManager();
編寫如下方法(這裡使用的是非同步函式):
export
async
function
checkAccessTokenID(
permission:
Array<Permissions>) {
// 獲取應用程式的accessTokenID
let
tokenId: number;
let
grantStatus:
Array<abilityAccessCtrl.
GrantStatus> = []
try {
let
bundleInfo: bundleManager.
BundleInfo =
await bundleManager.
getBundleInfoForSelf(bundleManager.
BundleFlag.
GET_BUNDLE_INFO_WITH_APPLICATION);
let
appInfo: bundleManager.
ApplicationInfo = bundleInfo.
appInfo;
tokenId = appInfo.
accessTokenId;
}
catch (err) {
console.
error(
`getBundleInfoForSelf failed, code is
${err.code}, message is
${err.message}`);
}
// 校驗應用是否被授予許可權,若申請多個許可權,建議迴圈檢查多個許可權
for (
let index =
0;index < permission.
length; index++) {
try {
grantStatus.
push(
await atManager.
checkAccessToken(tokenId, permission[index]))
}
catch (err) {
console.
error(
`checkAccessToken failed, code is
${err.code}, message is
${err.message}`);
}
}
return grantStatus;
}
export
async
function
checkPermission(
context: common.UIAbilityContext, permissions:
Array<Permissions>) {
let
grantStatus:
Array<abilityAccessCtrl.
GrantStatus> =
await
checkAccessTokenID(permissions)
for (
let i =
0; i < grantStatus.
length; i++) {
if (grantStatus[i] === abilityAccessCtrl.
GrantStatus.
PERMISSION_GRANTED) {
console.
info(
`
${permissions[i].toString()} 已授權`)
}
else {
//申請許可權
console.
info(
'開始向使用者申請許可權')
requestPermissionFromUser(context, permissions)
}
}
}
export
async
function
requestPermissionFromUser(
context: common.UIAbilityContext, permissions:
Array<Permissions>) {
// requestPermissionsFromUser會判斷許可權的授權狀態來決定是否喚起彈窗
atManager.
requestPermissionsFromUser(context, permissions).
then(
(
data) => {
let
grantStatus:
Array<number> = data.
authResults
let
length: number = grantStatus.
length
for (
let i =
0;i < length; i++) {
if (grantStatus[i] ===
0) {
// 使用者授權,可以繼續訪問目標操作
console.
info(
`
${permissions[i].toString()} 許可權申請成功`)
}
else {
// 使用者拒絕授權,提示使用者必須授權才能訪問當前頁面的功能,並引導使用者到系統設定中開啟相應的許可權
console.
info(
`
${permissions[i].toString()} 許可權申請被使用者拒絕`)
}
}
// 授權成功
})
}
此時,我們申請許可權的方法就算編寫完成了,在應用入口,即 EntryAbility.ts 檔案中的
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam)
方法中回撥許可權申請函式:
requestPermissionFromUser(this.context, PERMISSIONS)
其中,PERMISSIONS 定義如下:const PERMISSIONS:Array<Permissions>=['ohos.permission.DISTRIBUTED_DATASYNC']
到此,我們的許可權申請就算完完全全完成啦,當使用者第一次安裝並開啟應用的時候,應用會向使用者透過彈窗形式申請許可權,使用者點選授權即可賦予應用相應的許可權啦~
06、上手分散式資料物件程式碼開發
登入了同一華為帳號的 HarmonyOS 裝置已經預設了進行了組網認證,所以在進行分散式資料物件開發之前無需再進行多裝置組網認證這一階段的開發,開發變得相對簡單了起來。首先,我們們製作一個簡易 UI 介面(UI 介面僅供參考),如下圖所示:
相信對於有 HarmonyOS 開發經驗的小夥伴們來說這樣的 UI 介面製作並不困難,其中紅色圓點、綠色圓點為裝置狀態,當裝置狀態發生改變如下線時,顏色變為紅色,UI 介面程式碼如下:
import router
from
'@ohos.router'
import {
DistributedDeviceManageFunc }
from
'../modules/DistributedDeviceManager/DistributedDeviceManagerFunctions'
import
DistributedObjectFunc
from
'../modules/DistributedObject/DistributedObjectFunctions'
import {
ContinuationDeviceManagerDialog }
from
'../view/ContinuationDeviceManagerDialog'
import {
DistributedDeviceManagerDialog }
from
'../view/DistributedDeviceManagerDialog'
AppStorage.
SetOrCreate(
'distributedDeviceList', [])
AppStorage.
SetOrCreate(
'message',
'分散式資料物件Demo測試')
AppStorage.
SetOrCreate(
'statusColor',
'#ff4fc100')
AppStorage.
SetOrCreate(
'distributedColor',
'#ffff0000')
@Entry
@Component
struct
DistributedObjectDemo {
@StorageLink(
'message')
message:
string =
''
@StorageLink(
'statusColor')
statusColor:
string =
''
@StorageLink(
'distributedColor')
distributedColor:
string =
''
@StorageLink(
'distributedObj')
distributedObj:
DistributedObjectFunc =
new
DistributedObjectFunc()
@Builder
navigationTitle() {
Row({
space:
'10vp' }) {
Button({
type:
ButtonType.
Normal }) {
Image($rawfile(
'ic_public_back.svg'))
.
size({
width:
'24vp',
height:
'24vp'
})
}
.
width(
'36vp')
.
height(
'36vp')
.
backgroundColor(
Color.
White)
.
borderRadius(
'10vp')
.
onClick(
() => {
DistributedDeviceManageFunc.
release()
router.
back()
})
Text(
'分散式資料物件測試')
.
fontWeight(
FontWeight.
Bold)
.
fontSize(
'20vp')
Blank()
Button({
type:
ButtonType.
Normal }) {
Image($rawfile(
'ic_public_connection_filled.svg'))
.
size({
width:
'24vp',
height:
'24vp'
})
}
.
width(
'36vp')
.
height(
'36vp')
.
backgroundColor(
Color.
White)
.
borderRadius(
'10vp')
.
onClick(
() => {
this.
distributedDeviceManagerDialogController.
open()
})
}
.
padding(
'5vp')
.
width(
'90%')
}
build() {
Navigation() {
Column({
space:
'20vp' }) {
Row({
space:
'20vp' }) {
Text(
`裝置狀態`)
.
fontSize(
'20vp')
.
fontWeight(
FontWeight.
Bold)
Circle()
.
width(
'25vp')
.
height(
'25vp')
.
fill(
this.
statusColor)
}
Row({
space:
'20vp' }) {
Text(
`對端裝置狀態`)
.
fontSize(
'20vp')
.
fontWeight(
FontWeight.
Bold)
Circle()
.
width(
'25vp')
.
height(
'25vp')
.
fill(
this.
distributedColor)
}
Text(
`SessionID:
${
this.distributedObj.getSessionId()}`)
.
fontSize(
'20vp')
.
fontWeight(
FontWeight.
Bold)
Text(
this.
message)
.
fontSize(
'20vp')
.
fontWeight(
FontWeight.
Bold)
.
maxLines(
2)
Button(
'儲存分散式資料物件')
.
buttonStyles()
.
onClick(
() => {
this.
distributedObj.
saveDistributedObject()
})
Button(
'修改分散式資料物件')
.
buttonStyles()
.
onClick(
() => {
this.
distributedObj.
updateDistributedObject()
})
Button(
'退出組網')
.
buttonStyles()
.
onClick(
() => {
this.
distributedObj.
exit()
router.
back()
})
}
.
width(
'100%')
}
.
width(
'100%')
.
height(
'100%')
.
mode(
NavigationMode.
Auto)
.
titleMode(
NavigationTitleMode.
Mini)
.
hideBackButton(
true)
.
title(
this.
navigationTitle())
}
}
@Extend(
Button)
function
buttonStyles() {
.
fontSize(
'20vp')
.
width(
'60%')
.
height(
'50vp')
}
現在,我們的頁面製作就完成啦,下面開始重頭戲——分散式資料物件開發流程
1、匯入模組
import distributedObject from '@ohos.data.distributedDataObject'
2、初始化 distributedObject. DataObject 物件
定義一個 distributedObject. DataObject 型別的變數。
mDistributedObject: distributedObject.DataObject
呼叫 distributedObject. Create()函式建立一個 distributedObject. DataObject 物件,並將其返回給定義的變數 mDistributedObject。
this.mDistributedObject = distributedObject.create(globalThis.context, {
name: 'jack',
age: 18,
isVis: false
})
在 create()方法中存在兩個引數,context 和 resource,context 的型別為 Context,resource 型別為 object,在這裡我是在 entryAbility.ts 檔案下的 onWindowStageCreate()方法裡面定義了一個全域性變數 globalThis.context。
globalThis.context = this.context
3、設定組網 sessionId
this.mDistributedObject.setSessionId( this.mSessionId)
在 setSessionId()函式中,引數 sessionId 為 string 型別,表示分散式物件組網唯|一識別符號,設定同步的 sessionId,當可信組網中有多個裝置時,多個裝置間的物件如果設定為同一個 sessionId,就能自動同步。
4、開啟裝置狀態監聽
globalThis.
statusCallback =
(
sessionId:
string, networkId:
string, status:
string) => {
AppStorage.
Set(
'message',
`組網裝置狀況變更,id:
${sessionId} status:
${status} networkId:
${networkId}`)
if (status ==
'online') {
AppStorage.
Set(
'distributedColor',
'#ff4fc100')
}
else
if (status ==
'offline') {
AppStorage.
Set(
'distributedColor',
'#ffff0000')
}
}
this.
mDistributedObject.
on(
"status", globalThis.
statusCallback)
(sessionId: string, networkId: string, status: string)為 callback 回撥函式返回的值,我們可以使用這些返回值判斷裝置上下線狀態,其中 status 引數返回值為 online 或者 offline,表示裝置對端裝置上下線。
5、開啟分散式資料物件同步監聽
globalThis.
changeCallback =
(
sessionId:
string, fields:
Array<
string>) => {
console.
info(
'分散式資料物件發生變化')
if (fields !=
null && fields !=
undefined) {
AppStorage.
Set(
'message',
`data change:
${fields} sessionId:
${sessionId}`)
}
}
this.
mDistributedObject.
on(
"change", globalThis.
changeCallback)
當同一組網內分散式資料物件發生改變時,同一組網中的所有分散式資料物件同步發生變化,變化後的值為某一分散式資料物件改變後的值(sessionId: string, fields: Array<string>)為 callback 回撥函式返回值,其中,sessionId 為組網唯|一識別符號,field 為分散式資料物件的資料變更列表。
此時此刻,分散式資料物件就基本上開發完成啦。
如果有小夥伴想要修改分散式資料物件的屬性,可以直接修改
// @ts-ignore
this.mDistributedObject.name = 'lucy'
// @ts-ignore
this.mDistributedObject.age = 25
注意:根據當前版本 IDE 的編碼外掛情況,不能直接寫 this.mDistributedObject.age = 25,此時我們們需要加上// @ts-ignore 就可以啦。
最後,使用完分散式資料物件後大家要記得釋放資源哦(登出所有監聽,退出組網 sessionId,將分散式資料物件設定為空值)
this.mDistributedObject.off( "change")
this.mDistributedObject.off( "status")
this.mDistributedObject.setSessionId()
this.mDistributedObject = null
this.mSessionId = null
如果有小夥伴有兩部或兩部以上的華為裝置,可以將程式燒錄到裝置中,體驗一下分散式資料物件能力的快樂~
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70009402/viewspace-2999321/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用Taro開發鴻蒙原生應用——快速上手,鴻蒙應用開發指南鴻蒙
- 使用 Taro 開發鴻蒙原生應用 —— 快速上手,鴻蒙應用開發指南鴻蒙
- 加速鴻蒙生態共建,螞蟻mPaaS助力鴻蒙原生應用開發創新鴻蒙
- 米哈遊宣佈啟動鴻蒙原生應用開發鴻蒙
- 《三國殺》完成鴻蒙原生應用開發,更多遊戲品類加入鴻蒙生態鴻蒙遊戲
- 鴻蒙Next資料同步藝術:分散式物件與跨裝置呼叫鴻蒙分散式物件
- 雷霆遊戲加入鴻蒙“朋友圈”,《問道》手遊啟動鴻蒙原生應用開發遊戲鴻蒙
- 鴻蒙OS 2.0應用開發初潮鴻蒙
- 鴻蒙原生應用開發及部署:開啟HarmonyOS NEXT App新紀元鴻蒙APP
- 鷹角網路宣佈將啟動鴻蒙原生應用開發鴻蒙
- 《保衛蘿蔔4》僅用一個月完成鴻蒙原生應用開發鴻蒙
- 鴻蒙系統應用基礎開發鴻蒙
- 鴻蒙生態夥伴SDK市場正式釋出,驅動千行百業鴻蒙原生應用開發鴻蒙
- 【鴻蒙千帆起】《開心消消樂》完成鴻蒙原生應用開發,創新多端聯動使用者體驗鴻蒙
- 鴻蒙系統應用開發之開發準備鴻蒙
- 鴻蒙 Android iOS 應用開發對比02鴻蒙AndroidiOS
- 如何快速開發一個鴻蒙原生app鴻蒙APP
- 永珍革新,開啟鴻蒙原生應用生態新篇章鴻蒙
- 鴻蒙應用開發-DevEco Studio 模板體驗(四)鴻蒙dev
- 鴻蒙應用開發-DevEco Studio 模板體驗(一)鴻蒙dev
- 鴻蒙應用開發-DevEco Studio 模板體驗(三)鴻蒙dev
- 自學鴻蒙應用開發(17)- TabList和Tab鴻蒙
- 優酷鴻蒙開發實踐 | 鴻蒙卡片開發鴻蒙
- 鴻蒙開發TypeScript語言:【函式】鴻蒙TypeScript函式
- 鴻蒙真的是套殼嗎?HarmonyOS應用開發初體驗,Java原生和JavaScript的mvvm開發鴻蒙JavaScriptMVVM
- 鴻蒙系統應用開發之入門解說鴻蒙
- 庫洛遊戲宣佈《戰雙帕彌什》將啟動鴻蒙原生應用開發遊戲鴻蒙
- 中手遊全面啟動鴻蒙原生應用開發,為遊戲產業發展注入新活力鴻蒙遊戲產業
- 鴻蒙系統系列教程2-鴻蒙OS系統分散式操作講解鴻蒙分散式
- 嗶哩嗶哩遊戲宣佈《碧藍航線》將啟動鴻蒙原生應用開發遊戲鴻蒙
- 鴻蒙開發案例:直尺鴻蒙
- 鴻蒙JS 開發整理鴻蒙JS
- 鴻蒙Next應用本地化:資源管理鴻蒙
- 軟通動力鴻蒙書籍《HarmonyOS應用開發》正式出版鴻蒙
- 鴻蒙資料驅動鴻蒙
- 鴻蒙系統應用開發之基於API6的藍芽開發鴻蒙API藍芽
- DevEco Studio 2.0開發鴻蒙HarmonyOS應用初體驗全面測評dev鴻蒙
- 鴻蒙開發案例:指南針鴻蒙