0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙HarmonyOS開(kāi)發(fā)實(shí)例:【分布式關(guān)系型數(shù)據(jù)庫(kù)】

jf_46214456 ? 來(lái)源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-11 09:52 ? 次閱讀

分布式關(guān)系型數(shù)據(jù)庫(kù)

介紹

本示例使用[@ohos.data.relationalStore]接口和[@ohos.distributedDeviceManager] 接口展示了在eTS中分布式關(guān)系型數(shù)據(jù)庫(kù)的使用,在增、刪、改、查的基本操作外,還包括分布式數(shù)據(jù)庫(kù)的數(shù)據(jù)同步同能。

效果預(yù)覽

image.png

使用說(shuō)明:

  1. 啟動(dòng)應(yīng)用后點(diǎn)擊“ + ”按鈕可以添加聯(lián)系人;
  2. 點(diǎn)擊聯(lián)系人可以進(jìn)入編輯界面編輯聯(lián)系人信息;
  3. 長(zhǎng)按聯(lián)系人進(jìn)入多選狀態(tài),底部有“ 全選 ”、“ 取消 ”、“ 刪除 ”、“ 退出 ”按鈕,點(diǎn)擊退出可以退出多選狀態(tài);
  4. 點(diǎn)擊右上角更多按鈕,點(diǎn)擊“ 連接設(shè)備 ”,選擇要同步數(shù)據(jù)的設(shè)備,連接成功后可以開(kāi)始將本端數(shù)據(jù)同步到對(duì)端;
  5. 點(diǎn)擊右上角更多按鈕,點(diǎn)擊“ 設(shè)置 ”可以進(jìn)入設(shè)置界面設(shè)置數(shù)據(jù)同步方式,包括自動(dòng)同步和手動(dòng)同步。
    搜狗高速瀏覽器截圖20240326151547.png

具體實(shí)現(xiàn)

  • 數(shù)據(jù)庫(kù)的增、刪、改、查操作都在RdbModel中,源碼參考[RdbModel.ets]:
/*

 * Copyright (c) 2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import data_rdb from '@ohos.data.relationalStore'

import common from '@ohos.app.ability.common'

import Contact from '../model/Contact'

import Logger from '../model/Logger'

import { STORE_CONFIG } from '../model/RdbConst'

import { ValuesBucket } from '@ohos.data.ValuesBucket';



const TAG = 'RdbModel'



export default class RdbModel {

  private rdbStore: data_rdb.RdbStore | undefined = undefined

  private tableName: string = ''

  private sqlCreateTable: string = ''

  private columns: Array< string > = []

  private distributedTable: string = ''

  private dataChangeCallback : Function| null = null

  private isCreateDbDone: boolean = false

  private context: common.UIAbilityContext



  constructor(tableName: string, sqlCreateTable: string, columns: Array< string >, context: common.UIAbilityContext) {

    this.tableName = tableName

    this.sqlCreateTable = sqlCreateTable

    this.columns = columns

    this.context = context



    this.getRdbStore()

  }



  // 初始化數(shù)據(jù)庫(kù)

  async getRdbStore() {

    Logger.info(TAG, 'getRdbStore begin')

    if (this.isCreateDbDone) {

      Logger.info(TAG, 'getRdbStore isCreateDbDone')

      return

    }

    try {

      // 獲取數(shù)據(jù)庫(kù)存儲(chǔ)對(duì)象

      this.rdbStore = await data_rdb.getRdbStore(this.context, STORE_CONFIG);

    } catch (err) {

      console.info(`getRdbStore err ${JSON.stringify(err)}`);

    }

    Logger.info(TAG, 'getRdbStore end')

    try {

      // 執(zhí)行sql語(yǔ)句,聯(lián)系人個(gè)各個(gè)屬性設(shè)定

      if(this.rdbStore != undefined) {

        await this.rdbStore.executeSql(this.sqlCreateTable)

        console.info(`create tabe start ` + this.sqlCreateTable);

        // 設(shè)置分布式表,表明為contact

        await this.rdbStore.setDistributedTables([this.tableName])

      }

    } catch (e) {

      Logger.error(TAG, 'getRdbStore:' + JSON.stringify(e))

    }

    // 分布式數(shù)據(jù)庫(kù)創(chuàng)建為完成

    this.isCreateDbDone = true

    Logger.info(TAG, 'create table done')

  }



  async insertData(contact: Contact) {

    let value1 = contact.name;

    let value2 = contact.gender;

    let value3 = contact.phone;

    let value4 = contact.remark;

    let value5 = contact.age;



    const valueBucket: ValuesBucket = {

      'name': value1,

      'gender': value2,

      'phone': value3,

      'remark': value4,

      'age': value5,

    }

    if(this.rdbStore != undefined) {

      let ret = await this.rdbStore.insert(this.tableName, valueBucket, data_rdb.ConflictResolution.ON_CONFLICT_REPLACE)

      Logger.info(TAG, `insert done:${ret}`)

    }

  }



  async updateData(contact: Contact) {

    let value1 = contact.name;

    let value2 = contact.gender;

    let value3 = contact.phone;

    let value4 = contact.remark;

    let value5 = contact.age;



    const valueBucket: ValuesBucket = {

      'name': value1,

      'gender': value2,

      'phone': value3,

      'remark': value4,

      'age': value5,

    }

    let predicates = new data_rdb.RdbPredicates(this.tableName)

    Logger.info(TAG, `updateData id=${contact.id}`)

    predicates.equalTo('id', contact.id)

    if (this.rdbStore != undefined) {

      let ret = await this.rdbStore.update(valueBucket, predicates)

      Logger.info(TAG, `updated row count: ${ret}`)

    }

  }



  async deleteContacts(contacts: Array< Contact >) {

    let predicates = new data_rdb.RdbPredicates(this.tableName)

    contacts.forEach((contact) = > {

      predicates.or()

        .equalTo('id', contact.id)

    })

    if (this.rdbStore != undefined) {

      let rows = await this.rdbStore.delete(predicates)

      Logger.info(TAG, `delete rows: ${rows}`)

    }

  }



  async query(predicates: data_rdb.RdbPredicates): Promise< Array< Contact >> {

    Logger.info(TAG, 'query start')

    Logger.info(TAG, 'predicates is ' + JSON.stringify(predicates))

    Logger.info(TAG, 'columns ' + JSON.stringify(this.columns))

    if (this.rdbStore != undefined) {

      // 默認(rèn)查詢(xún)所有列

      let resultSet: data_rdb.ResultSet = await this.rdbStore.query(predicates, this.columns);

      Logger.info(TAG, 'result is ' + JSON.stringify(resultSet.rowCount))

      // 處理查詢(xún)到的結(jié)果數(shù)組

      return this.getListFromResultSet(resultSet)

    }

    return []

  }



  async syncData(predicates: data_rdb.RdbPredicates) {

    Logger.info(TAG, 'syncData')

    if (this.rdbStore != undefined) {

      let result = await this.rdbStore.sync(data_rdb.SyncMode.SYNC_MODE_PUSH, predicates)

      for (let i = 0; i < result.length; i++) {

        Logger.info(TAG, `device=${result[i][0]}, status = ${result[i][1]}`)

      }

    }

  }



  async onDataChange(device: string, callback: Function) {

    Logger.info(TAG, `onDataChange enter,device=` + device + ` ,tableName = ` + this.tableName)

    try {

      if (this.rdbStore != undefined) {

        this.distributedTable = await this.rdbStore.obtainDistributedTableName(device, this.tableName)

        Logger.info(TAG, `obtainDistributedTableName,distributedTable=` + this.distributedTable)

      }

    }

    catch (err) {

      Logger.error(TAG, `ObtainDistributedTableName failed, code is ${err.code},message is ${err.message}`)

    }

    this.dataChangeCallback = callback

    await this.pullData()

    if (this.rdbStore != undefined) {

      this.rdbStore.on('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, async (devices) = > {

        Logger.info(TAG, `on dataChange, callback`)

        await this.pullData()

      })

    }

  }



  async pullData() {

    Logger.info(TAG, `start pullData`)

    if (this.rdbStore != undefined) {

      await this.rdbStore.executeSql('delete from ' + this.tableName)

      let predicates = new data_rdb.RdbPredicates(this.distributedTable)

      let resultSet = await this.rdbStore.query(predicates, this.columns)

      let result = this.getListFromResultSet(resultSet)

      Logger.info(TAG, `on dataChange,result.length=${result.length}`)

      for (let i = 0; i < result.length; i++) {

        Logger.info(TAG, `on dataChange,insert${result[i].name}`)

        let predicate = new data_rdb.RdbPredicates(this.tableName)

        predicate.equalTo('name', result[i].name)

        let exit = await this.rdbStore.query(predicate, this.columns)

        exit.goToFirstRow()

        if (exit.rowCount === 0) {

          await this.insertData(result[i])

        } else {

          result[i].id = exit.getDouble(resultSet.getColumnIndex('id'))

          await this.updateData(result[i])

        }

      }

      if (this.dataChangeCallback != null) {

        this.dataChangeCallback(result)

      }

    }

  }



  offDataChange() {

    if(this.rdbStore != undefined) {

      this.rdbStore.off('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, (devices) = > {

        for (let i = 0; i < devices.length; i++) {

          Logger.info(TAG, `device=${devices[i]} off data changed`)

        }

      })

    }

  }



  // 處理數(shù)據(jù)格式

  getListFromResultSet(resultSet: data_rdb.ResultSet): Array< Contact > {

    // 聲明結(jié)果變量

    let contacts: Array< Contact > = []

    // 進(jìn)入結(jié)果集的第一行

    resultSet.goToFirstRow()

    // 如果沒(méi)有結(jié)束就繼續(xù)遍歷

    while (!resultSet.isEnded) {

      // 讀取各個(gè)屬性,初始化臨時(shí)變量contact

      let contact: Contact = new Contact(resultSet.getDouble(resultSet.getColumnIndex('id'))

        , resultSet.getString(resultSet.getColumnIndex('name'))

        , resultSet.getDouble(resultSet.getColumnIndex('gender'))

        , resultSet.getString(resultSet.getColumnIndex('phone'))

        , resultSet.getLong(resultSet.getColumnIndex('age'))

        , resultSet.getString(resultSet.getColumnIndex('remark')))

      if (!contacts.includes(contact)) {

        // 如果數(shù)據(jù)集合中沒(méi)有這條數(shù)據(jù)就添加進(jìn)去

        contacts.push(contact)

      }

      // 進(jìn)入下一行

      resultSet.goToNextRow()

    }

    // 數(shù)據(jù)整合完畢就釋放資源

    resultSet.close()

    Logger.info(TAG, 'contacts number is ' + contacts.length)

    // 返回整合的聯(lián)系人數(shù)據(jù)

    return contacts

  }

}
  • 數(shù)據(jù)庫(kù)操作:使用[@ohos.data.relationalStore] 接口的getRdbStore獲得一個(gè)相關(guān)的操作型關(guān)系數(shù)據(jù)庫(kù)RdbStore,通過(guò)這個(gè)RdbStore調(diào)用相關(guān)接口進(jìn)行增刪改查,RdbStore.insert數(shù)據(jù)插入,RdbStore.delete數(shù)據(jù)刪除,RdbStore.update更新數(shù)據(jù),RdbStore.query根據(jù)條件查詢(xún)數(shù)據(jù);
  • 數(shù)據(jù)同步:RdbStore.on注冊(cè)數(shù)據(jù)庫(kù)觀察者,使用RdbStore.obtainDistributedTableName根據(jù)本地表名獲取指定遠(yuǎn)程設(shè)備的分布式表名,數(shù)據(jù)發(fā)生變動(dòng)時(shí)通過(guò)RdbStore.sync同步數(shù)據(jù),不需要用時(shí)刪除指定觀察者使用RdbStore.off。
  • 連接設(shè)備管理在RemoteDeviceModel中,源碼參考[RemoteDeviceModel.ets]:
/*

 * Copyright (c) 2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import deviceManager from '@ohos.distributedDeviceManager';

import Logger from '../model/Logger'

import { BUNDLE } from '../model/RdbConst'

import { BusinessError } from '@ohos.base';



let SUBSCRIBE_ID = 100

const TAG: string = 'RemoteDeviceModel'

class Data {

  device: deviceManager.DeviceBasicInfo = {

    deviceId: "",

    deviceName: "",

    deviceType: "",

    networkId: "",

  }

}

class RemoteDeviceModel {

  public deviceList: Array< deviceManager.DeviceBasicInfo > = [];

  public discoverList: Array< deviceManager.DeviceBasicInfo > = [];

  private callback: () = > void = () = > {};

  private authCallback: (device: deviceManager.DeviceBasicInfo) = > void = (device: deviceManager.DeviceBasicInfo) = > '';

  private deviceManager: deviceManager.DeviceManager | undefined = undefined



  registerDeviceListCallback(callback: () = > void) {

    if (typeof (this.deviceManager) !== 'undefined') {

      this.registerDeviceListCallbackImplement(callback)

      return

    }

    Logger.info(TAG, 'deviceManager.createDeviceManager begin')

    try {

      let dmInstance = deviceManager.createDeviceManager(BUNDLE);

      Logger.info(TAG, `dmInstance= ${JSON.stringify (dmInstance)}`);

      this.deviceManager = dmInstance;

      this.registerDeviceListCallbackImplement(callback);

      Logger.info(TAG, `createDeviceManager callback returned, value= ${JSON.stringify(this.deviceManager)}`);

    } catch (error) {

      Logger.error(TAG, `createDeviceManager throw error, code: ${(error as BusinessError).code} message: ${(error as BusinessError).message}`);

    }

    Logger.info(TAG, 'deviceManager.createDeviceManager end');

  }



  deviceStateChangeActionOnline(device: deviceManager.DeviceBasicInfo) {

    this.deviceList[this.deviceList.length] = device

    Logger.info(TAG, `online, device list=${JSON.stringify(this.deviceList)}`)

    if (this.authCallback !== undefined) {

      this.authCallback(device)

      this.authCallback = () = > {}

    }

  }



  deviceStateChangeActionReady(device: deviceManager.DeviceBasicInfo) {

    if (this.deviceList.length <= 0) {

      this.callback()

      return

    }

    let list: Array< deviceManager.DeviceBasicInfo > = new Array()

    for (let i = 0; i < this.deviceList.length; i++) {

      if (this.deviceList[i].deviceId !== device.deviceId) {

        list[i] = device

      }

    }

    this.deviceList = list

    Logger.info(TAG, `ready, device list=${JSON.stringify(this.deviceList)}`)

    this.callback()

  }



  deviceStateChangeActionOffline(device: deviceManager.DeviceBasicInfo) {

    if (this.deviceList.length <= 0) {

      this.callback()

      return

    }

    for (let j = 0; j < this.deviceList.length; j++) {

      if (this.deviceList[j].deviceId === device.deviceId) {

        this.deviceList[j] = device

        break

      }

    }

    Logger.info(TAG, `offline, device list=${JSON.stringify(this.deviceList)}`)

  }



  getLocalDevice(): string {

    Logger.info(TAG, `getLocalDevice`);

    if(this.deviceManager != undefined) {

      let deviceId: string = this.deviceManager.getLocalDeviceId();

      Logger.info(TAG, `local deviceInfo=${JSON.stringify(deviceId)}`);

      return deviceId;

    }

    return ''

  }



  registerDeviceListCallbackImplement(callback: () = > void) {

    Logger.info(TAG, 'registerDeviceListCallback' + JSON.stringify(this.deviceManager))

    this.callback = callback

    if (this.deviceManager === undefined) {

      Logger.error(TAG, 'deviceManager has not initialized')

      this.callback()

      return

    }

    Logger.info(TAG, 'getTrustedDeviceListSync begin' + JSON.stringify(this.deviceManager));

    let list = this.deviceManager.getAvailableDeviceListSync();

    Logger.info(TAG, `getTrustedDeviceListSync end, deviceList=${JSON.stringify(list)}`)

    if (typeof (list) !== 'undefined' && typeof (list.length) !== 'undefined') {

      this.deviceList = list

    }

    this.callback()

    Logger.info(TAG, 'callback finished')

    this.deviceManager.on('deviceStateChange', (data) = > {

      Logger.info(TAG, 'deviceStateChange on:' + JSON.stringify(data));

      if (data === null) {

        return

      }

      switch (data.action) {

        case deviceManager.DeviceStateChange.UNKNOWN:

          this.deviceStateChangeActionOnline(data.device)

          break

        case deviceManager.DeviceStateChange.AVAILABLE:

          this.deviceStateChangeActionReady(data.device)

          break

        case deviceManager.DeviceStateChange.UNAVAILABLE:

          this.deviceStateChangeActionOffline(data.device)

          break

        default:

          break

      }

    })

    this.deviceManager.on('discoverSuccess', (data: Data) = > {

      if (data === null) {

        return

      }

      Logger.info(TAG, `discoverSuccess data=${JSON.stringify(data)}`);

      this.deviceFound(data);

    })

    this.deviceManager.on('discoverFailure', (data) = > {

      Logger.info(TAG, `discoverFailure data=${JSON.stringify(data)}`);

    })

    this.deviceManager.on('serviceDie', () = > {

      Logger.info(TAG, 'serviceDie')

    })

    this.startDeviceDiscovery()

  }



  deviceFound(data: Data) {

    if(data != undefined) {

      if (data.device != undefined) {

        for (let i = 0; i < this.discoverList.length; i++) {

          if (this.discoverList[i].deviceId === data.device.deviceId) {

            Logger.info(TAG, 'device founded ignored')

            return

          }

        }

        this.discoverList[this.discoverList.length] = data.device

        Logger.info(TAG, `deviceFound self.discoverList=${JSON.stringify(this.discoverList)}`);

        this.callback()

      }

    }

  }



  startDeviceDiscovery() {

    let discoverParam: Record< string, number > = {

      'discoverTargetType': 1

    };

    let filterOptions: Record< string, number > = {

      'availableStatus': 0

    };

    Logger.info(TAG, `startDeviceDiscovery${SUBSCRIBE_ID}`);

    try {

      if(this.deviceManager != undefined) {

        this.deviceManager.startDiscovering(discoverParam, filterOptions);

      }

    } catch (error) {

      Logger.error(TAG, `startDeviceDiscovery throw error, code: ${(error as BusinessError).code} message: ${(error as BusinessError).message}`);

    }

  }



  unregisterDeviceListCallback() {

    if(this.deviceManager != undefined) {

      Logger.info(TAG, `stopDeviceDiscovery${SUBSCRIBE_ID}`);

      this.deviceManager.stopDiscovering();

      this.deviceManager.off('deviceStateChange');

      this.deviceManager.off('discoverSuccess');

      this.deviceManager.off('discoverFailure');

      this.deviceManager.off('serviceDie');

    }

    this.deviceList = [];

    this.discoverList = [];

  }



  authenticateDevice(device: deviceManager.DeviceBasicInfo, callBack: (device: deviceManager.DeviceBasicInfo) = > void) {

    Logger.info(TAG, `bindTarget${JSON.stringify(device)}`);

    for (let i = 0; i < this.discoverList.length; i++) {

      if (this.discoverList[i].deviceId !== device.deviceId) {

        continue

      }

      if (this.deviceManager === undefined) {

        return

      }

      try {

        if (this.deviceManager !== null) {

          this.deviceManager.bindTarget(device.deviceId, {

            bindType: 1,

            targetPkgName: BUNDLE,

            appName: 'Distributed distributedrdb',

          }, (err, data) = > {

            if (err) {

              Logger.error(TAG, `authenticateDevice throw error, code: ${(err as BusinessError).code} message: ${(err as BusinessError).message}`);

              this.authCallback = () = > {

              }

              return

            }

            Logger.debug(TAG, `authenticateDevice succeed: ${JSON.stringify(data)}`);

            this.authCallback = callBack;

          })

        }

      } catch (error) {

        Logger.error(TAG, `authenticateDevice throw error, code: ${(error as BusinessError).code} message: ${(error as BusinessError).message}`);

      }

    }

  }

}



export default new RemoteDeviceModel()
  • 設(shè)備同步:設(shè)備同步數(shù)據(jù)需要[ohos.permission.DISTRIBUTED_DATASYNC] 權(quán)限,在頁(yè)面渲染前申請(qǐng)權(quán)限,源碼參考[Index.ets],
/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import data_rdb from '@ohos.data.relationalStore'

import common from '@ohos.app.ability.common'

import Want from '@ohos.app.ability.Want'

import router from '@ohos.router'

import Contact from '../model/Contact'

import ContactDataSource from '../common/BasicDataSource'

import LiteStore from '../model/LiteStore'

import Logger from '../model/Logger'

import RdbModel from '../model/RdbModel'

import { BottomBtn } from '../common/BottomBtn'

import { ContactItem } from '../common/ContactItem'

import { PopupMenu } from '../common/PopupMenu'

import { SyncState } from '../model/LiteStore'

import { SearchBar } from '../common/SearchBar'

import { TitleBar } from '../common/TitleBar'

import { TABLE_NAME, BUNDLE, ABILITY, SQL_CREATE_TABLE, COLUMNS } from '../model/RdbConst'



const TAG: string = 'Index'



export interface stateType {

  popupMenu: boolean,

  isDistributed: boolean,

  isStage: boolean,

  selectedIndex: number,

  syncState: string,

  distributedDevice: string,

  opacityValue: number

}

@Entry

@Component

struct Index {

  private liteStore = new LiteStore("sync_state", getContext(this) as common.UIAbilityContext)

  private rdbModel = new RdbModel(TABLE_NAME, SQL_CREATE_TABLE, COLUMNS, getContext(this) as common.UIAbilityContext)

  private intervalId: number = 0

  @State contacts: ContactDataSource = new ContactDataSource([])

  @State isMultiCheck: boolean = false

  @State isSelectedAll: boolean = false

  @State state: stateType = {

    popupMenu: false,

    isDistributed: false,

    isStage: false,

    selectedIndex: 0,

    syncState: SyncState.ManualSync,

    distributedDevice: '',

    opacityValue: 1

  }



  async aboutToAppear() {

    Logger.info(TAG, 'aboutToAppear')

    await this.rdbModel.getRdbStore();

    await this.getData();

  }



  // 拉起應(yīng)用后讀取數(shù)據(jù),暫定為分布式功能

  getWant() {

    let want = AppStorage.Get< Want >('want') as Want

    if(want.parameters != undefined) {

      if (this.state.isDistributed && want.parameters.isStage === 'EXIT') {

        Logger.info(TAG, 'isStage = EXIT')

        this.state.isStage = false

        this.state.isDistributed = false

        this.state.selectedIndex = 0

        this.state.distributedDevice = ''

        this.rdbModel.offDataChange()

      }

      if (!this.state.isDistributed && want.parameters.isStage === 'Stage') {

        Logger.info(TAG, 'isStage = Stage')

        this.state.isStage = true

        this.state.isDistributed = true

        this.state.distributedDevice = want.parameters.dmsSrcNetworkId as string;

        let context = getContext(this) as common.UIAbilityContext

        context.startAbility({

          bundleName: BUNDLE,

          abilityName: ABILITY,

          deviceId: this.state.distributedDevice,

          parameters: {

            isStage: 'CONNECT'

          }

        })

        Logger.info(TAG, 'onDataChange')

        this.rdbModel.onDataChange(this.state.distributedDevice, (result: Array< Contact >)= > {

        this.contacts.dataArray = result

          this.contacts.notifyDataReload()

        })

      }

    }

  }



  async onPageShow() {

    try {

      // 初始化分部署數(shù)據(jù)庫(kù)

      await this.rdbModel.getRdbStore()

      this.intervalId = setInterval(() = > {

        // 手動(dòng)偵聽(tīng)?wèi)?yīng)用被拉起的動(dòng)作

        this.getWant()

      }, 1000)

      // 讀取數(shù)據(jù)庫(kù)數(shù)據(jù)

      await this.getData()

    } catch (err) {

      Logger.error('onPageShow:' + JSON.stringify(err))

    }

  }



  async getData() {

    Logger.info(TAG, 'getData')

    // 初始化數(shù)據(jù)庫(kù)的表,表名為contact

    let predicates = new data_rdb.RdbPredicates(TABLE_NAME)

    // 讀取表中的數(shù)據(jù)

    this.contacts.replaceDataArray(await this.rdbModel.query(predicates));

    // 通知懶加載數(shù)據(jù)變更

    this.contacts.notifyDataReload()

    Logger.info(TAG, 'getData contacts count' + this.contacts.dataArray.length)

    // 讀取Preferences中的數(shù)據(jù)

    let syncState = await this.liteStore.getValue()

    this.state.syncState = `${syncState}`

    if (!this.state.isStage && this.state.isDistributed && syncState === SyncState.AutomaticSync) {

      await this.syncData()

    }

  }



  showDeleteDialog() {

    let deleteContacts: Contact[] = []

    this.contacts.dataArray.forEach((contact) = > {

      if (contact.isSelected) {

        deleteContacts.push(contact)

      }

    })

    if (deleteContacts.length == 0) {

      return

    }

    AlertDialog.show({

      message: $r('app.string.delete_contact'),

      primaryButton: {

        value: $r('app.string.sure'),

        fontColor: Color.Red,

        action: async () = > {

          await this.rdbModel.deleteContacts(deleteContacts)

          await this.getData()

          this.quitMultiCheck()

        }

      },

      secondaryButton: {

        value: $r('app.string.cancel'),

        fontColor: Color.Blue,

        action: () = > {

        }

      }

    })

  }



  handleClickContact(item: Contact, index: number) {

    Logger.info(TAG, `handleClickContact, item = ${JSON.stringify(item)}`)

    if (this.isMultiCheck) {

      let tempContacts = this.contacts.dataArray

      this.contacts.dataArray = []

      tempContacts[index].isSelected = !item.isSelected

      this.contacts.dataArray = tempContacts

      this.contacts.notifyDataReload()

    } else {

      router.pushUrl({

        url: 'pages/ContactEdit',

        params: { contact: item, isInsert: false }

      })

    }

  }



  refreshSelectState(isSelect: boolean) {

    this.contacts.dataArray.forEach((contact) = > {

      contact.isSelected = isSelect

    })

    this.contacts.notifyDataReload()

  }



  quitMultiCheck() {

    this.isSelectedAll = false

    this.refreshSelectState(this.isSelectedAll)

    this.isMultiCheck = false

  }



  handleBottomBtnClick = (index: number) = > {

    switch (index) {

      case 0:

        this.isSelectedAll = !this.isSelectedAll

        this.refreshSelectState(this.isSelectedAll)

        break

      case 1:

        this.showDeleteDialog()

        break

      case 2:

        this.quitMultiCheck()

        break

      default:

        break

    }

  }

  handleRightBtn = () = > {

    this.state.popupMenu = true;

    this.state.opacityValue = 1;

  }

  syncData = () = > {

    Logger.info(TAG, 'sync data')

    let predicates = new data_rdb.RdbPredicates(TABLE_NAME)

    predicates.inAllDevices()

    this.rdbModel.syncData(predicates)

  }



  build() {

    Stack({ alignContent: Alignment.BottomEnd }) {

      Column() {

        Stack() {

          if (this.state.isStage) {

            TitleBar()

          } else {

            TitleBar({ rightBtn: $r('app.media.more'), handleRightBtn: this.handleRightBtn })

          }

          if (this.state.isDistributed && !this.state.isStage && this.state.syncState === SyncState.ManualSync) {

            Row() {

              Blank()



              Image($r('app.media.ic_syncto'))

                .size({ width: 50, height: 60 })

                .onClick(this.syncData)

            }.width('80%')

          }

        }.width('100%')



        SearchBar()

        List() {

          LazyForEach(this.contacts, (item: Contact, index) = > {

            ListItem() {

              ContactItem({ contact: item, isMultiCheck: $isMultiCheck })

            }

            .onClick(() = > {

              this.handleClickContact(item, index)

            })

          }, (item: Contact) = > JSON.stringify(item))

        }

        .width('100%')

        .layoutWeight(1)

        .padding({ left: 10, right: 10 })

        .divider({ strokeWidth: 1, color: Color.Gray, startMargin: 16, endMargin: 16 })

      }

      .width('100%')

      .height('100%')



      if (this.state.popupMenu) {

        PopupMenu({ state: $state, handleStartAbility: this.syncData })

      }



      BottomBtn({

        isMultiCheck: this.isMultiCheck,

        isSelectedAll: this.isSelectedAll,

        handleBottomBtnClick: this.handleBottomBtnClick

      })



      if (!this.isMultiCheck && !this.state.isStage) {

        Button() {

          Image($r('app.media.add'))

            .height('100%')

            .width('100%')

            .objectFit(ImageFit.Contain)

            .align(Alignment.End)

        }

        .id('btnAdd')

        .width(80)

        .height(80)

        .margin({ right: 20, bottom: 50 })

        .type(ButtonType.Circle)

        .backgroundColor('#0D9FFB')

        .onClick(() = > {

          Logger.info(TAG, 'onClick')

          router.pushUrl({

            url: 'pages/ContactEdit',

            params: { contact: new Contact(0, '', 0, '', -1, ''), isInsert: true }

          })

        })

      }

    }

    .width('100%')

    .height('100%')

  }



  onBackPress() {

    Logger.info(TAG, 'onBackPress')

    let context = getContext(this) as common.UIAbilityContext

    context.startAbility({

      bundleName: BUNDLE,

      abilityName: ABILITY,

      deviceId: this.state.distributedDevice,

      parameters: {

        isStage: 'EXIT'

      }

    })

    this.rdbModel.offDataChange()

  }



  onPageHide() {

    Logger.info(TAG, 'onBackPress')

    clearInterval(this.intervalId)

  }

}

使用[@ohos.distributedDeviceManager]接口,首先通過(guò)createDeviceManager創(chuàng)建設(shè)備管理器實(shí)例,然后通過(guò)getTrustedDeviceListSync同步獲取所有可信設(shè)備列表;

  • 設(shè)備連接:首先通過(guò)on方法注冊(cè)設(shè)備狀態(tài),例如發(fā)現(xiàn)設(shè)備,設(shè)備連接失敗,然后通過(guò)startDeviceDiscovery方法發(fā)現(xiàn)周邊設(shè)備,然后選擇連接設(shè)備,再用[startAbility]啟動(dòng)連接設(shè)備的應(yīng)用。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3734

    瀏覽量

    64170
  • 分布式
    +關(guān)注

    關(guān)注

    1

    文章

    842

    瀏覽量

    74422
  • 鴻蒙
    +關(guān)注

    關(guān)注

    57

    文章

    2287

    瀏覽量

    42629
  • HarmonyOS
    +關(guān)注

    關(guān)注

    79

    文章

    1954

    瀏覽量

    29897
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3607

    瀏覽量

    15958
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    一文講清什么是分布式云化數(shù)據(jù)庫(kù)!

    分布式云化數(shù)據(jù)庫(kù)是一種先進(jìn)的數(shù)據(jù)管理系統(tǒng),它將傳統(tǒng)的數(shù)據(jù)庫(kù)技術(shù)與分布式計(jì)算、云計(jì)算和大數(shù)據(jù)處理技
    的頭像 發(fā)表于 10-14 10:06 ?103次閱讀

    基于分布式存儲(chǔ)WDS的金融信創(chuàng)云承載數(shù)據(jù)庫(kù)類(lèi)關(guān)鍵應(yīng)用

    基于分布式存儲(chǔ)WDS的金融信創(chuàng)云承載數(shù)據(jù)庫(kù)類(lèi)關(guān)鍵應(yīng)用
    的頭像 發(fā)表于 08-16 09:42 ?188次閱讀
    基于<b class='flag-5'>分布式</b>存儲(chǔ)WDS的金融信創(chuàng)云承載<b class='flag-5'>數(shù)據(jù)庫(kù)</b>類(lèi)關(guān)鍵應(yīng)用

    鴻蒙開(kāi)發(fā)接口數(shù)據(jù)管理:【@ohos.data.rdb (關(guān)系數(shù)據(jù)庫(kù))】

    關(guān)系數(shù)據(jù)庫(kù)(Relational Database,RDB)是一種基于關(guān)系模型來(lái)管理數(shù)據(jù)數(shù)據(jù)庫(kù)
    的頭像 發(fā)表于 06-10 18:35 ?1119次閱讀

    鴻蒙開(kāi)發(fā)接口數(shù)據(jù)管理:【@ohos.data.distributedData (分布式數(shù)據(jù)管理)】

    分布式數(shù)據(jù)管理為應(yīng)用程序提供不同設(shè)備間數(shù)據(jù)庫(kù)分布式協(xié)同能力。通過(guò)調(diào)用分布式數(shù)據(jù)各個(gè)接口,應(yīng)用程
    的頭像 發(fā)表于 06-07 09:30 ?802次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>開(kāi)發(fā)</b>接口<b class='flag-5'>數(shù)據(jù)</b>管理:【@ohos.data.distributedData (<b class='flag-5'>分布式</b><b class='flag-5'>數(shù)據(jù)</b>管理)】

    HarmonyOS開(kāi)發(fā)案例:【搭建關(guān)系數(shù)據(jù)庫(kù)】(4)

    本節(jié)將介紹如何調(diào)用關(guān)系數(shù)據(jù)庫(kù)接口在本地搭建數(shù)據(jù)庫(kù),并讀寫(xiě)相應(yīng)的用戶(hù)數(shù)據(jù)。
    的頭像 發(fā)表于 05-11 10:27 ?694次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開(kāi)發(fā)</b>案例:【搭建<b class='flag-5'>關(guān)系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫(kù)</b>】(4)

    HarmonyOS開(kāi)發(fā)案例:【關(guān)系數(shù)據(jù)庫(kù)

    使用關(guān)系數(shù)據(jù)庫(kù)的相關(guān)接口實(shí)現(xiàn)了對(duì)賬單的增、刪、改、查操作。
    的頭像 發(fā)表于 04-22 14:58 ?591次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開(kāi)發(fā)</b>案例:【<b class='flag-5'>關(guān)系</b><b class='flag-5'>型</b><b class='flag-5'>數(shù)據(jù)庫(kù)</b>】

    HarmonyOS開(kāi)發(fā)實(shí)例:【分布式數(shù)據(jù)服務(wù)】

    分布式數(shù)據(jù)服務(wù)(Distributed Data Service,DDS)為應(yīng)用程序提供不同設(shè)備間數(shù)據(jù)分布式的能力。
    的頭像 發(fā)表于 04-18 10:18 ?611次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開(kāi)發(fā)</b><b class='flag-5'>實(shí)例</b>:【<b class='flag-5'>分布式</b><b class='flag-5'>數(shù)據(jù)</b>服務(wù)】

    HarmonyOS開(kāi)發(fā)實(shí)例:【分布式手寫(xiě)板】

    使用設(shè)備管理及分布式鍵值數(shù)據(jù)庫(kù)能力,實(shí)現(xiàn)多設(shè)備之間手寫(xiě)板應(yīng)用拉起及同步書(shū)寫(xiě)內(nèi)容的功能。
    的頭像 發(fā)表于 04-17 21:45 ?412次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開(kāi)發(fā)</b><b class='flag-5'>實(shí)例</b>:【<b class='flag-5'>分布式</b>手寫(xiě)板】

    HarmonyOS開(kāi)發(fā)實(shí)例:【分布式郵件】

    基于TS擴(kuò)展的聲明開(kāi)發(fā)范式編程語(yǔ)言編寫(xiě)的一個(gè)分布式郵件系統(tǒng),可以由一臺(tái)設(shè)備拉起另一臺(tái)設(shè)備,每次改動(dòng)郵件內(nèi)容,都會(huì)同步更新兩臺(tái)設(shè)備的信息
    的頭像 發(fā)表于 04-17 10:29 ?691次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開(kāi)發(fā)</b><b class='flag-5'>實(shí)例</b>:【<b class='flag-5'>分布式</b>郵件】

    HarmonyOS開(kāi)發(fā)實(shí)例:【分布式數(shù)據(jù)管理】

    eTS中分布式數(shù)據(jù)管理的使用,包括KVManager對(duì)象實(shí)例的創(chuàng)建和KVStore數(shù)據(jù)流轉(zhuǎn)的使用。
    的頭像 發(fā)表于 04-11 09:57 ?838次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開(kāi)發(fā)</b><b class='flag-5'>實(shí)例</b>:【<b class='flag-5'>分布式</b><b class='flag-5'>數(shù)據(jù)</b>管理】

    HarmonyOS開(kāi)發(fā)技術(shù)全面分析

    的快速連接、能力互助、資源共享,匹配合適的設(shè)備、提供流暢的全場(chǎng)景體驗(yàn)。 ? 對(duì)應(yīng)用開(kāi)發(fā)者而言, HarmonyOS 采用了多種分布式技術(shù),使得應(yīng)用程序的開(kāi)發(fā)實(shí)現(xiàn)與不同終端設(shè)備的形態(tài)差異
    發(fā)表于 02-21 16:31

    鴻蒙OS 分布式任務(wù)調(diào)度

    鴻蒙OS 分布式任務(wù)調(diào)度概述 在 HarmonyO S中,分布式任務(wù)調(diào)度平臺(tái)對(duì)搭載 HarmonyOS 的多設(shè)備構(gòu)筑的“超級(jí)虛擬終端”提供統(tǒng)一的組件管理能力,為應(yīng)用定義統(tǒng)一的能力基線、
    的頭像 發(fā)表于 01-29 16:50 ?422次閱讀

    鴻蒙原生應(yīng)用開(kāi)發(fā)——分布式數(shù)據(jù)對(duì)象

    申請(qǐng)權(quán)限,用戶(hù)點(diǎn)擊授權(quán)即可賦予應(yīng)用相應(yīng)的權(quán)限啦~ 06、上手分布式數(shù)據(jù)對(duì)象代碼開(kāi)發(fā) 登錄了同一華為帳號(hào)的 HarmonyOS 設(shè)備已經(jīng)默認(rèn)了進(jìn)行了組網(wǎng)認(rèn)證,所以在進(jìn)行
    發(fā)表于 12-08 10:01

    如何在HarmonyOS對(duì)數(shù)據(jù)庫(kù)進(jìn)行備份,恢復(fù)與加密

    backup接口實(shí)現(xiàn)數(shù)據(jù)庫(kù)備份,通過(guò)restore接口實(shí)現(xiàn)數(shù)據(jù)庫(kù)恢復(fù),通過(guò)deletebackup接口刪除數(shù)據(jù)庫(kù)備份。具體接口及功能,可見(jiàn)??分布式鍵值
    發(fā)表于 11-07 08:57

    HarmonyOS數(shù)據(jù)管理與應(yīng)用數(shù)據(jù)持久化(一)

    、手動(dòng)備份能力。分布式功能暫不支持。 ● 關(guān)系數(shù)據(jù)管理(RelationalStore):提供了關(guān)系
    發(fā)表于 11-01 16:27