吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

鴻蒙HarmonyOS開發實例:【分布式關系型數據庫】

jf_46214456 ? 來源:jf_46214456 ? 作者:jf_46214456 ? 2024-04-11 09:52 ? 次閱讀

分布式關系型數據庫

介紹

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

效果預覽

image.png

使用說明:

  1. 啟動應用后點擊“ + ”按鈕可以添加聯系人;
  2. 點擊聯系人可以進入編輯界面編輯聯系人信息;
  3. 長按聯系人進入多選狀態,底部有“ 全選 ”、“ 取消 ”、“ 刪除 ”、“ 退出 ”按鈕,點擊退出可以退出多選狀態;
  4. 點擊右上角更多按鈕,點擊“ 連接設備 ”,選擇要同步數據的設備,連接成功后可以開始將本端數據同步到對端;
  5. 點擊右上角更多按鈕,點擊“ 設置 ”可以進入設置界面設置數據同步方式,包括自動同步和手動同步。
    搜狗高速瀏覽器截圖20240326151547.png

具體實現

  • 數據庫的增、刪、改、查操作都在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()

  }



  // 初始化數據庫

  async getRdbStore() {

    Logger.info(TAG, 'getRdbStore begin')

    if (this.isCreateDbDone) {

      Logger.info(TAG, 'getRdbStore isCreateDbDone')

      return

    }

    try {

      // 獲取數據庫存儲對象

      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 {

      // 執行sql語句,聯系人個各個屬性設定

      if(this.rdbStore != undefined) {

        await this.rdbStore.executeSql(this.sqlCreateTable)

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

        // 設置分布式表,表明為contact

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

      }

    } catch (e) {

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

    }

    // 分布式數據庫創建為完成

    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) {

      // 默認查詢所有列

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

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

      // 處理查詢到的結果數組

      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`)

        }

      })

    }

  }



  // 處理數據格式

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

    // 聲明結果變量

    let contacts: Array< Contact > = []

    // 進入結果集的第一行

    resultSet.goToFirstRow()

    // 如果沒有結束就繼續遍歷

    while (!resultSet.isEnded) {

      // 讀取各個屬性,初始化臨時變量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)) {

        // 如果數據集合中沒有這條數據就添加進去

        contacts.push(contact)

      }

      // 進入下一行

      resultSet.goToNextRow()

    }

    // 數據整合完畢就釋放資源

    resultSet.close()

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

    // 返回整合的聯系人數據

    return contacts

  }

}
  • 數據庫操作:使用[@ohos.data.relationalStore] 接口的getRdbStore獲得一個相關的操作型關系數據庫RdbStore,通過這個RdbStore調用相關接口進行增刪改查,RdbStore.insert數據插入,RdbStore.delete數據刪除,RdbStore.update更新數據,RdbStore.query根據條件查詢數據;
  • 數據同步:RdbStore.on注冊數據庫觀察者,使用RdbStore.obtainDistributedTableName根據本地表名獲取指定遠程設備的分布式表名,數據發生變動時通過RdbStore.sync同步數據,不需要用時刪除指定觀察者使用RdbStore.off。
  • 連接設備管理在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()
  • 設備同步:設備同步數據需要[ohos.permission.DISTRIBUTED_DATASYNC] 權限,在頁面渲染前申請權限,源碼參考[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();

  }



  // 拉起應用后讀取數據,暫定為分布式功能

  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 {

      // 初始化分部署數據庫

      await this.rdbModel.getRdbStore()

      this.intervalId = setInterval(() = > {

        // 手動偵聽應用被拉起的動作

        this.getWant()

      }, 1000)

      // 讀取數據庫數據

      await this.getData()

    } catch (err) {

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

    }

  }



  async getData() {

    Logger.info(TAG, 'getData')

    // 初始化數據庫的表,表名為contact

    let predicates = new data_rdb.RdbPredicates(TABLE_NAME)

    // 讀取表中的數據

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

    // 通知懶加載數據變更

    this.contacts.notifyDataReload()

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

    // 讀取Preferences中的數據

    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]接口,首先通過createDeviceManager創建設備管理器實例,然后通過getTrustedDeviceListSync同步獲取所有可信設備列表;

  • 設備連接:首先通過on方法注冊設備狀態,例如發現設備,設備連接失敗,然后通過startDeviceDiscovery方法發現周邊設備,然后選擇連接設備,再用[startAbility]啟動連接設備的應用。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據庫
    +關注

    關注

    7

    文章

    3846

    瀏覽量

    64684
  • 分布式
    +關注

    關注

    1

    文章

    924

    瀏覽量

    74610
  • 鴻蒙
    +關注

    關注

    57

    文章

    2392

    瀏覽量

    43048
  • HarmonyOS
    +關注

    關注

    79

    文章

    1982

    瀏覽量

    30570
  • OpenHarmony
    +關注

    關注

    25

    文章

    3744

    瀏覽量

    16575
收藏 人收藏

    評論

    相關推薦

    分布式云化數據庫有哪些類型

    分布式云化數據庫有哪些類型?分布式云化數據庫主要類型包括:關系
    的頭像 發表于 01-15 09:43 ?110次閱讀

    關系數據庫和非關系區別

    關系數據庫和非關系數據庫在多個方面存在顯著差異,主機推薦小編為您整理發布
    的頭像 發表于 01-10 09:58 ?120次閱讀

    HarmonyOS Next 應用元服務開發-分布式數據對象遷移數據權限與基礎數據

    設備文件訪問實現文件的遷移,難以獲取文件同步完成的時間。為了保證更高的成功率,文件的遷移不建議繼續通過該方式實現,推薦使用分布式數據對象攜帶資產的方式。開發者此前通過跨設備文件訪問實現的文件遷移依然生效
    發表于 12-24 09:40

    一文講清什么是分布式云化數據庫

    分布式云化數據庫是一種先進的數據管理系統,它將傳統的數據庫技術與分布式計算、云計算和大數據處理技
    的頭像 發表于 10-14 10:06 ?261次閱讀

    基于分布式存儲WDS的金融信創云承載數據庫類關鍵應用

    基于分布式存儲WDS的金融信創云承載數據庫類關鍵應用
    的頭像 發表于 08-16 09:42 ?322次閱讀
    基于<b class='flag-5'>分布式</b>存儲WDS的金融信創云承載<b class='flag-5'>數據庫</b>類關鍵應用

    鴻蒙開發接口數據管理:【@ohos.data.rdb (關系數據庫)】

    關系數據庫(Relational Database,RDB)是一種基于關系模型來管理數據數據庫
    的頭像 發表于 06-10 18:35 ?1420次閱讀

    鴻蒙開發接口數據管理:【@ohos.data.distributedData (分布式數據管理)】

    分布式數據管理為應用程序提供不同設備間數據庫分布式協同能力。通過調用分布式數據各個接口,應用程
    的頭像 發表于 06-07 09:30 ?1070次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>開發</b>接口<b class='flag-5'>數據</b>管理:【@ohos.data.distributedData (<b class='flag-5'>分布式</b><b class='flag-5'>數據</b>管理)】

    HarmonyOS開發案例:【搭建關系數據庫】(4)

    本節將介紹如何調用關系數據庫接口在本地搭建數據庫,并讀寫相應的用戶數據。
    的頭像 發表于 05-11 10:27 ?992次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b>案例:【搭建<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數據庫</b>】(4)

    HarmonyOS開發案例:【關系數據庫

    使用關系數據庫的相關接口實現了對賬單的增、刪、改、查操作。
    的頭像 發表于 04-22 14:58 ?691次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b>案例:【<b class='flag-5'>關系</b><b class='flag-5'>型</b><b class='flag-5'>數據庫</b>】

    HarmonyOS開發實例:【分布式數據服務】

    分布式數據服務(Distributed Data Service,DDS)為應用程序提供不同設備間數據分布式的能力。
    的頭像 發表于 04-18 10:18 ?794次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b><b class='flag-5'>實例</b>:【<b class='flag-5'>分布式</b><b class='flag-5'>數據</b>服務】

    HarmonyOS開發實例:【分布式手寫板】

    使用設備管理及分布式鍵值數據庫能力,實現多設備之間手寫板應用拉起及同步書寫內容的功能。
    的頭像 發表于 04-17 21:45 ?574次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b><b class='flag-5'>實例</b>:【<b class='flag-5'>分布式</b>手寫板】

    HarmonyOS開發實例:【分布式新聞客戶端】

    基于柵格布局、設備管理和多端協同,實現一次開發,多端部署的分布式新聞客戶端頁面。
    的頭像 發表于 04-17 15:57 ?929次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b><b class='flag-5'>實例</b>:【<b class='flag-5'>分布式</b>新聞客戶端】

    HarmonyOS開發實例:【分布式郵件】

    基于TS擴展的聲明開發范式編程語言編寫的一個分布式郵件系統,可以由一臺設備拉起另一臺設備,每次改動郵件內容,都會同步更新兩臺設備的信息
    的頭像 發表于 04-17 10:29 ?803次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b><b class='flag-5'>實例</b>:【<b class='flag-5'>分布式</b>郵件】

    HarmonyOS開發實例:【分布式數據管理】

    eTS中分布式數據管理的使用,包括KVManager對象實例的創建和KVStore數據流轉的使用。
    的頭像 發表于 04-11 09:57 ?982次閱讀
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>開發</b><b class='flag-5'>實例</b>:【<b class='flag-5'>分布式</b><b class='flag-5'>數據</b>管理】

    HarmonyOS開發技術全面分析

    的快速連接、能力互助、資源共享,匹配合適的設備、提供流暢的全場景體驗。 ? 對應用開發者而言, HarmonyOS 采用了多種分布式技術,使得應用程序的開發實現與不同終端設備的形態差異
    發表于 02-21 16:31
    百家乐注册下注平台| 大发888开户博盈国际| 24山分房法| 中华百家乐官网娱乐城| 平顺县| bet365足球| 大发888怎么下载安装| 澳门百家乐游戏官网| 网上百家乐大赢家| 网上百家乐导航| 百家乐注册开户送现金| 百家乐游戏机压法| 网上百家乐新利| 百家乐如何看牌| 互博百家乐现金网| 金公主百家乐现金网| 博九网百家乐现金网| 百家乐大小技巧| 百家乐开户优惠多的平台是哪家| 做生意仓库和办公桌在家里是不是讲风水 | 乌审旗| 百家乐官网信誉平台开户| 立博百家乐官网游戏| 百家乐官网无敌直缆| 保时捷百家乐官网娱乐城| 百家乐官网赌法博彩正网| 皇室百家乐官网娱乐城| 任你博百家乐官网现金网| 百家乐官网娱乐城备用网址| 百家乐官网赌场技巧大全| 百家乐官网凯时娱乐网| 三公百家乐官网在线哪里可以玩| 百家乐平注法到656| 全讯网bbin888.com| 大发888游戏攻略| 网上澳门| 菲律宾百家乐官网游戏| 百家乐官网赌场网| 百家乐官网画面方法| 百家乐下注几多| 百家乐套装|