介绍
本示例使用[@ohos.data.relationalStore]接口和[@ohos.distributedDeviceManager] 接口展示了在eTS中分布式关系型数据库的使用,在增、删、改、查的基本操作外,还包括分布式数据库的数据同步同能。
效果预览
使用说明:
- 启动应用后点击“ + ”按钮可以添加联系人;
- 点击联系人可以进入编辑界面编辑联系人信息;
- 长按联系人进入多选状态,底部有“全选”、“取消”、“删除”、“退出”按钮,点击退出可以退出多选状态;
- 点击右上角更多按钮,点击“连接设备”,选择要同步数据的设备,连接成功后可以开始将本端数据同步到对端;
- 点击右上角更多按钮,点击“设置”可以进入设置界面设置数据同步方式,包括自动同步和手动同步。
具体实现
- 数据库的增、删、改、查操作都在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 = undefinedprivate tableName: string = ''private sqlCreateTable: string = ''private columns: Array<string> = []private distributedTable: string = ''private dataChangeCallback : Function| null = nullprivate isCreateDbDone: boolean = falseprivate context: common.UIAbilityContextconstructor(tableName: string, sqlCreateTable: string, columns: Array<string>, context: common.UIAbilityContext) {this.tableName = tableNamethis.sqlCreateTable = sqlCreateTablethis.columns = columnsthis.context = contextthis.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);// 设置分布式表,表明为contactawait this.rdbStore.setDistributedTables([this.tableName])}} catch (e) {Logger.error(TAG, 'getRdbStore:' + JSON.stringify(e))}// 分布式数据库创建为完成this.isCreateDbDone = trueLogger.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 = callbackawait 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) {// 读取各个属性,初始化临时变量contactlet 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 = 100const 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 = undefinedregisterDeviceListCallback(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] = deviceLogger.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 = listLogger.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] = devicebreak}}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 = callbackif (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)breakcase deviceManager.DeviceStateChange.AVAILABLE:this.deviceStateChangeActionReady(data.device)breakcase deviceManager.DeviceStateChange.UNAVAILABLE:this.deviceStateChangeActionOffline(data.device)breakdefault: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.deviceLogger.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@Componentstruct 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 Wantif(want.parameters != undefined) {if (this.state.isDistributed && want.parameters.isStage === 'EXIT') {Logger.info(TAG, 'isStage = EXIT')this.state.isStage = falsethis.state.isDistributed = falsethis.state.selectedIndex = 0this.state.distributedDevice = ''this.rdbModel.offDataChange()}if (!this.state.isDistributed && want.parameters.isStage === 'Stage') {Logger.info(TAG, 'isStage = Stage')this.state.isStage = truethis.state.isDistributed = truethis.state.distributedDevice = want.parameters.dmsSrcNetworkId as string;let context = getContext(this) as common.UIAbilityContextcontext.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 = resultthis.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')// 初始化数据库的表,表名为contactlet 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.dataArraythis.contacts.dataArray = []tempContacts[index].isSelected = !item.isSelectedthis.contacts.dataArray = tempContactsthis.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 = falsethis.refreshSelectState(this.isSelectedAll)this.isMultiCheck = false}handleBottomBtnClick = (index: number) => {switch (index) {case 0:this.isSelectedAll = !this.isSelectedAllthis.refreshSelectState(this.isSelectedAll)breakcase 1:this.showDeleteDialog()breakcase 2:this.quitMultiCheck()breakdefault: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.UIAbilityContextcontext.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]启动连接设备的应用。
最后呢,很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。
而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点
如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。
高清完整版请点击→《鸿蒙NEXT星河版开发学习文档》
针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细资料鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。
《鸿蒙 (OpenHarmony)开发学习视频》
《鸿蒙生态应用开发V2.0白皮书》
《鸿蒙 (OpenHarmony)开发基础到实战手册》
获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》
OpenHarmony北向、南向开发环境搭建
《鸿蒙开发基础》
-
ArkTS语言
-
安装DevEco Studio
-
运用你的第一个ArkTS应用
-
ArkUI声明式UI开发
-
.……
《鸿蒙开发进阶》
-
Stage模型入门
-
网络管理
-
数据管理
-
电话服务
-
分布式应用开发
-
通知与窗口管理
-
多媒体技术
-
安全技能
-
任务管理
-
WebGL
-
国际化开发
-
应用测试
-
DFX面向未来设计
-
鸿蒙系统移植和裁剪定制
-
……
《鸿蒙开发实战》
-
ArkTS实践
-
UIAbility应用
-
网络案例
-
……
获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》
总结
鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。
并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!