鸿蒙开发(API 12 Beta6版)【通用属性协议】 网络篇

简介

通用属性协议是GATT(Generic Attribute)的缩写,它是一种用于在蓝牙低功耗设备之间传输数据的协议,定义了一套通用的属性和服务框架。通过GATT协议,蓝牙设备可以向其他设备提供服务,也可以从其他设备获取服务。

场景介绍

主要场景有:

  • 连接server端读取和写入信息。
  • server端操作services和通知客户端信息。

接口说明

具体接口说明如下表。

接口名 功能描述
connect() client端发起连接远端蓝牙低功耗设备。
disconnect() client端断开与远端蓝牙低功耗设备的连接。
close() 关闭客户端功能,注销client在协议栈的注册,调用该接口后GattClientDevice实例将不能再使用。
getDeviceName() client获取远端蓝牙低功耗设备名。
getServices() client端获取蓝牙低功耗设备的所有服务,即服务发现 。
readCharacteristicValue() client端读取蓝牙低功耗设备特定服务的特征值。
readDescriptorValue() client端读取蓝牙低功耗设备特定的特征包含的描述符。
writeCharacteristicValue() client端向低功耗蓝牙设备写入特定的特征值。
writeDescriptorValue() client端向低功耗蓝牙设备特定的描述符写入二进制数据。
getRssiValue() client获取远端蓝牙低功耗设备的信号强度 (Received Signal Strength Indication, RSSI),调用connect接口连接成功后才能使用。
setBLEMtuSize() client协商远端蓝牙低功耗设备的最大传输单元(Maximum Transmission Unit, MTU),调用connect接口连接成功后才能使用。
setCharacteristicChangeNotification() 向服务端发送设置通知此特征值请求。
setCharacteristicChangeIndication() 向服务端发送设置通知此特征值请求。
on(type: 'BLECharacteristicChange') 订阅蓝牙低功耗设备的特征值变化事件。需要先调用setNotifyCharacteristicChanged接口才能接收server端的通知。
off(type: 'BLECharacteristicChange') 取消订阅蓝牙低功耗设备的特征值变化事件。
on(type: 'BLEConnectionStateChange') client端订阅蓝牙低功耗设备的连接状态变化事件。
off(type: 'BLEConnectionStateChange') 取消订阅蓝牙低功耗设备的连接状态变化事件。
on(type: 'BLEMtuChange') client端订阅MTU状态变化事件。
off(type: 'BLEMtuChange') client端取消订阅MTU状态变化事件。
addService() server端添加服务。
removeService() 删除已添加的服务。
close() 关闭服务端功能,去注销server在协议栈的注册,调用该接口后GattServer实例将不能再使用。
notifyCharacteristicChanged() server端特征值发生变化时,主动通知已连接的client设备。
sendResponse() server端回复client端的读写请求。
on(type: 'characteristicRead') server端订阅特征值读请求事件。
off(type: 'characteristicRead') server端取消订阅特征值读请求事件。
on(type: 'characteristicWrite') server端订阅特征值写请求事件。
off(type: 'characteristicWrite') server端取消订阅特征值写请求事件。
on(type: 'descriptorRead') server端订阅描述符读请求事件。
off(type: 'descriptorRead') server端取消订阅描述符读请求事件。
on(type: 'descriptorWrite') server端订阅描述符写请求事件。
off(type: 'descriptorWrite') server端取消订阅描述符写请求事件。
on(type: 'connectionStateChange') server端订阅BLE连接状态变化事件。
off(type: 'connectionStateChange') server端取消订阅BLE连接状态变化事件。
on(type: 'BLEMtuChange') server端订阅MTU状态变化事件。
off(type: 'BLEMtuChange') server端取消订阅MTU状态变化事件。

主要场景开发步骤

连接server端读取和写入信息

  1. import需要的ble模块。

  2. 创建gattClient实例对象。

  3. 连接gattServer。

  4. 读取gattServer的特征值和描述符。

  5. 向gattServer写入特征值和描述符。

  6. 断开连接,销毁gattClient实例。

  7. 示例代码:

    import { ble } from '@kit.ConnectivityKit';
    import { constant } from '@kit.ConnectivityKit';
    import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';

    const TAG: string = 'GattClientManager';

    export class GattClientManager {
    device: string = undefined;
    gattClient: ble.GattClientDevice = undefined;
    connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
    myServiceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
    myCharacteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
    myFirstDescriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB'; // 2902一般用于notification或者indication
    mySecondDescriptorUuid: string = '00002903-0000-1000-8000-00805F9B34FB';
    found: boolean = false;

    // 构造BLEDescriptor
    private initDescriptor(des: string, value: ArrayBuffer): ble.BLEDescriptor {
    let descriptor: ble.BLEDescriptor = {
    serviceUuid: this.myServiceUuid,
    characteristicUuid: this.myCharacteristicUuid,
    descriptorUuid: des,
    descriptorValue: value
    };
    return descriptor;
    }

    // 构造BLECharacteristic
    private initCharacteristic(): ble.BLECharacteristic {
    let descriptors: Array<ble.BLEDescriptor> = [];
    let descBuffer = new ArrayBuffer(2);
    let descValue = new Uint8Array(descBuffer);
    descValue[0] = 11;
    descValue[1] = 12;
    descriptors[0] = this.initDescriptor(this.myFirstDescriptorUuid, new ArrayBuffer(2));
    descriptors[1] = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
    let charBuffer = new ArrayBuffer(2);
    let charValue = new Uint8Array(charBuffer);
    charValue[0] = 1;
    charValue[1] = 2;
    let characteristic: ble.BLECharacteristic = {
    serviceUuid: this.myServiceUuid,
    characteristicUuid: this.myCharacteristicUuid,
    characteristicValue: charBuffer,
    descriptors: descriptors
    };
    return characteristic;
    }

    private logCharacteristic(char: ble.BLECharacteristic) {
    let message = 'logCharacteristic uuid:' + char.characteristicUuid + '\n';
    let value = new Uint8Array(char.characteristicValue);
    message += 'logCharacteristic value: ';
    for (let i = 0; i < char.characteristicValue.byteLength; i++) {
    message += value[i] + ' ';
    }
    console.info(TAG, message);
    }

    private logDescriptor(des: ble.BLEDescriptor) {
    let message = 'logDescriptor uuid:' + des.descriptorUuid + '\n';
    let value = new Uint8Array(des.descriptorValue);
    message += 'logDescriptor value: ';
    for (let i = 0; i < des.descriptorValue.byteLength; i++) {
    message += value[i] + ' ';
    }
    console.info(TAG, message);
    }

    private checkService(services: Array<ble.GattService>): boolean {
    for (let i = 0; i < services.length; i++) {
    if (services[i].serviceUuid != this.myServiceUuid) {
    continue;
    }
    for (let j = 0; j < services[i].characteristics.length; j++) {
    if (services[i].characteristics[j].characteristicUuid != this.myCharacteristicUuid) {
    continue;
    }
    for (let k = 0; k < services[i].characteristics[j].descriptors.length; k++) {
    if (services[i].characteristics[j].descriptors[k].descriptorUuid == this.myFirstDescriptorUuid) {
    console.info(TAG, 'find expected service from server');
    return true;
    }
    }
    }
    }
    console.error(TAG, 'no expected service from server');
    return false;
    }

    // 1. 订阅连接状态变化事件
    public onGattClientStateChange() {
    if (!this.gattClient) {
    console.error(TAG, 'no gattClient');
    return;
    }
    try {
    this.gattClient.on('BLEConnectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
    let state = '';
    switch (stateInfo.state) {
    case 0:
    state = 'DISCONNECTED';
    break;
    case 1:
    state = 'CONNECTING';
    break;
    case 2:
    state = 'CONNECTED';
    break;
    case 3:
    state = 'DISCONNECTING';
    break;
    default:
    state = 'undefined';
    break;
    }
    console.info(TAG, 'onGattClientStateChange: device=' + stateInfo.deviceId + ', state=' + state);
    if (stateInfo.deviceId == this.device) {
    this.connectState = stateInfo.state;
    }
    });
    } catch (err) {
    console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
    }

    // 2. client端主动连接时调用
    public startConnect(peerDevice: string) { // 对端设备一般通过ble scan获取到
    if (this.connectState != constant.ProfileConnectionState.STATE_DISCONNECTED) {
    console.error(TAG, 'startConnect failed');
    return;
    }
    console.info(TAG, 'startConnect ' + peerDevice);
    this.device = peerDevice;
    // 2.1 使用device构造gattClient,后续的交互都需要使用该实例
    this.gattClient = ble.createGattClientDevice(peerDevice);
    try {
    this.onGattClientStateChange(); // 2.2 订阅连接状态
    this.gattClient.connect(); // 2.3 发起连接
    } catch (err) {
    console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
    }

    // 3. client端连接成功后,需要进行服务发现
    public discoverServices() {
    if (!this.gattClient) {
    console.info(TAG, 'no gattClient');
    return;
    }
    console.info(TAG, 'discoverServices');
    try {
    this.gattClient.getServices().then((result: Array<ble.GattService>) => {
    console.info(TAG, 'getServices success: ' + JSON.stringify(result));
    this.found = this.checkService(result); // 要确保server端的服务内容有业务所需要的服务
    });
    } catch (err) {
    console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
    }

    // 4. 在确保拿到了server端的服务结果后,读取server端特定服务的特征值时调用
    public readCharacteristicValue() {
    if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
    console.error(TAG, 'no gattClient or not connected');
    return;
    }
    if (!this.found) { // 要确保server端有对应的characteristic
    console.error(TAG, 'no characteristic from server');
    return;
    }

     let characteristic = this.initCharacteristic();
     console.info(TAG, 'readCharacteristicValue');
     try {
       this.gattClient.readCharacteristicValue(characteristic).then((outData: ble.BLECharacteristic) => {
         this.logCharacteristic(outData);
       })
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 5. 在确保拿到了server端的服务结果后,写入server端特定服务的特征值时调用
    public writeCharacteristicValue() {
    if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
    console.error(TAG, 'no gattClient or not connected');
    return;
    }
    if (!this.found) { // 要确保server端有对应的characteristic
    console.error(TAG, 'no characteristic from server');
    return;
    }

     let characteristic = this.initCharacteristic();
     console.info(TAG, 'writeCharacteristicValue');
     try {
       this.gattClient.writeCharacteristicValue(characteristic, ble.GattWriteType.WRITE, (err) => {
         if (err) {
           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
           return;
         }
         console.info(TAG, 'writeCharacteristicValue success');
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 6. 在确保拿到了server端的服务结果后,读取server端特定服务的描述符时调用
    public readDescriptorValue() {
    if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
    console.error(TAG, 'no gattClient or not connected');
    return;
    }
    if (!this.found) { // 要确保server端有对应的descriptor
    console.error(TAG, 'no descriptor from server');
    return;
    }

     let descBuffer = new ArrayBuffer(0);
     let descriptor = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
     console.info(TAG, 'readDescriptorValue');
     try {
       this.gattClient.readDescriptorValue(descriptor).then((outData: ble.BLEDescriptor) => {
         this.logDescriptor(outData);
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 7. 在确保拿到了server端的服务结果后,写入server端特定服务的描述符时调用
    public writeDescriptorValue() {
    if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
    console.error(TAG, 'no gattClient or not connected');
    return;
    }
    if (!this.found) { // 要确保server端有对应的descriptor
    console.error(TAG, 'no descriptor from server');
    return;
    }

     let descBuffer = new ArrayBuffer(2);
     let descValue = new Uint8Array(descBuffer);
     descValue[0] = 11;
     descValue[1] = 12;
     let descriptor = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
     console.info(TAG, 'writeDescriptorValue');
     try {
       this.gattClient.writeDescriptorValue(descriptor, (err) => {
         if (err) {
           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
           return;
         }
         console.info(TAG, 'writeDescriptorValue success');
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 8.client端主动断开时调用
    public stopConnect() {
    if (!this.gattClient || this.connectState != constant.ProfileConnectionState.STATE_CONNECTED) {
    console.error(TAG, 'no gattClient or not connected');
    return;
    }

     console.info(TAG, 'stopConnect ' + this.device);
     try {
       this.gattClient.disconnect(); // 8.1 断开连接
       this.gattClient.off('BLEConnectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
       });
       this.gattClient.close() // 8.2 如果不再使用此gattClient,则需要close
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }
    }

    let gattClientManager = new GattClientManager();
    export default gattClientManager as GattClientManager;

server端操作services和通知客户端信息

  1. import需要的ble模块。

  2. 创建gattServer实例对象。

  3. 添加services信息。

  4. 当向gattServer写入特征值通知gattClient。

  5. 移除services信息。

  6. 注销gattServer实例。

  7. 示例代码:

    import { ble } from '@kit.ConnectivityKit';
    import { constant } from '@kit.ConnectivityKit';
    import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';

    const TAG: string = 'GattServerManager';

    export class GattServerManager {
    gattServer: ble.GattServer = undefined;
    connectState: ble.ProfileConnectionState = constant.ProfileConnectionState.STATE_DISCONNECTED;
    myServiceUuid: string = '00001810-0000-1000-8000-00805F9B34FB';
    myCharacteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB';
    myFirstDescriptorUuid: string = '00002902-0000-1000-8000-00805F9B34FB'; // 2902一般用于notification或者indication
    mySecondDescriptorUuid: string = '00002903-0000-1000-8000-00805F9B34FB';

    // 构造BLEDescriptor
    private initDescriptor(des: string, value: ArrayBuffer): ble.BLEDescriptor {
    let descriptor: ble.BLEDescriptor = {
    serviceUuid: this.myServiceUuid,
    characteristicUuid: this.myCharacteristicUuid,
    descriptorUuid: des,
    descriptorValue: value
    };
    return descriptor;
    }

    // 构造BLECharacteristic
    private initCharacteristic(): ble.BLECharacteristic {
    let descriptors: Array<ble.BLEDescriptor> = [];
    let descBuffer = new ArrayBuffer(2);
    let descValue = new Uint8Array(descBuffer);
    descValue[0] = 31;
    descValue[1] = 32;
    descriptors[0] = this.initDescriptor(this.myFirstDescriptorUuid, new ArrayBuffer(2));
    descriptors[1] = this.initDescriptor(this.mySecondDescriptorUuid, descBuffer);
    let charBuffer = new ArrayBuffer(2);
    let charValue = new Uint8Array(charBuffer);
    charValue[0] = 21;
    charValue[1] = 22;
    let characteristic: ble.BLECharacteristic = {
    serviceUuid: this.myServiceUuid,
    characteristicUuid: this.myCharacteristicUuid,
    characteristicValue: charBuffer,
    descriptors: descriptors
    };
    return characteristic;
    }

    // 1. 订阅连接状态变化事件
    public onGattServerStateChange() {
    if (!this.gattServer) {
    console.error(TAG, 'no gattServer');
    return;
    }
    try {
    this.gattServer.on('connectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => {
    let state = '';
    switch (stateInfo.state) {
    case 0:
    state = 'DISCONNECTED';
    break;
    case 1:
    state = 'CONNECTING';
    break;
    case 2:
    state = 'CONNECTED';
    break;
    case 3:
    state = 'DISCONNECTING';
    break;
    default:
    state = 'undefined';
    break;
    }
    console.info(TAG, 'onGattServerStateChange: device=' + stateInfo.deviceId + ', state=' + state);
    });
    } catch (err) {
    console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
    }

    // 2. server端注册服务时调用
    public registerServer() {
    let characteristics: Array<ble.BLECharacteristic> = [];
    let characteristic = this.initCharacteristic();
    characteristics.push(characteristic);
    let gattService: ble.GattService = {
    serviceUuid: this.myServiceUuid,
    isPrimary: true,
    characteristics: characteristics
    };

     console.info(TAG, 'registerServer ' + this.myServiceUuid);
     try {
       this.gattServer = ble.createGattServer(); // 2.1 构造gattServer,后续的交互都需要使用该实例
       this.onGattServerStateChange(); // 2.2 订阅连接状态
       this.gattServer.addService(gattService);
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 3. 订阅来自gattClient的读取特征值请求时调用
    public onCharacteristicRead() {
    if (!this.gattServer) {
    console.error(TAG, 'no gattServer');
    return;
    }

     console.info(TAG, 'onCharacteristicRead');
     try {
       this.gattServer.on('characteristicRead', (charReq: ble.CharacteristicReadRequest) => {
         let deviceId: string = charReq.deviceId;
         let transId: number = charReq.transId;
         let offset: number = charReq.offset;
         console.info(TAG, 'receive characteristicRead');
         let rspBuffer = new ArrayBuffer(2);
         let rspValue = new Uint8Array(rspBuffer);
         rspValue[0] = 21;
         rspValue[1] = 22;
         let serverResponse: ble.ServerResponse = {
           deviceId: deviceId,
           transId: transId,
           status: 0, // 0表示成功
           offset: offset,
           value: rspBuffer
         };
    
         try {
           this.gattServer.sendResponse(serverResponse);
         } catch (err) {
           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
         }
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 4. 订阅来自gattClient的写入特征值请求时调用
    public onCharacteristicWrite() {
    if (!this.gattServer) {
    console.error(TAG, 'no gattServer');
    return;
    }

     console.info(TAG, 'onCharacteristicWrite');
     try {
       this.gattServer.on('characteristicWrite', (charReq: ble.CharacteristicWriteRequest) => {
         let deviceId: string = charReq.deviceId;
         let transId: number = charReq.transId;
         let offset: number = charReq.offset;
         console.info(TAG, 'receive characteristicWrite: needRsp=' + charReq.needRsp);
         if (!charReq.needRsp) {
           return;
         }
         let rspBuffer = new ArrayBuffer(0);
         let serverResponse: ble.ServerResponse = {
           deviceId: deviceId,
           transId: transId,
           status: 0, // 0表示成功
           offset: offset,
           value: rspBuffer
         };
    
         try {
           this.gattServer.sendResponse(serverResponse);
         } catch (err) {
           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
         }
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 5. 订阅来自gattClient的读取描述符请求时调用
    public onDescriptorRead() {
    if (!this.gattServer) {
    console.error(TAG, 'no gattServer');
    return;
    }

     console.info(TAG, 'onDescriptorRead');
     try {
       this.gattServer.on('descriptorRead', (desReq: ble.DescriptorReadRequest) => {
         let deviceId: string = desReq.deviceId;
         let transId: number = desReq.transId;
         let offset: number = desReq.offset;
         console.info(TAG, 'receive descriptorRead');
         let rspBuffer = new ArrayBuffer(2);
         let rspValue = new Uint8Array(rspBuffer);
         rspValue[0] = 31;
         rspValue[1] = 32;
         let serverResponse: ble.ServerResponse = {
           deviceId: deviceId,
           transId: transId,
           status: 0, // 0表示成功
           offset: offset,
           value: rspBuffer
         };
    
         try {
           this.gattServer.sendResponse(serverResponse);
         } catch (err) {
           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
         }
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 6. 订阅来自gattClient的写入描述符请求时调用
    public onDescriptorWrite() {
    if (!this.gattServer) {
    console.error(TAG, 'no gattServer');
    return;
    }

     console.info(TAG, 'onDescriptorWrite');
     try {
       this.gattServer.on('descriptorWrite', (desReq: ble.DescriptorWriteRequest) => {
         let deviceId: string = desReq.deviceId;
         let transId: number = desReq.transId;
         let offset: number = desReq.offset;
         console.info(TAG, 'receive descriptorWrite: needRsp=' + desReq.needRsp);
         if (!desReq.needRsp) {
           return;
         }
         let rspBuffer = new ArrayBuffer(0);
         let serverResponse: ble.ServerResponse = {
           deviceId: deviceId,
           transId: transId,
           status: 0, // 0表示成功
           offset: offset,
           value: rspBuffer
         };
    
         try {
           this.gattServer.sendResponse(serverResponse);
         } catch (err) {
           console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
         }
       });
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }

    // 7. server端删除服务,不再使用时调用
    public unRegisterServer() {
    if (!this.gattServer) {
    console.error(TAG, 'no gattServer');
    return;
    }

     console.info(TAG, 'unRegisterServer ' + this.myServiceUuid);
     try {
       this.gattServer.removeService(this.myServiceUuid); // 7.1 删除服务
       this.gattServer.off('connectionStateChange', (stateInfo: ble.BLEConnectionChangeState) => { // 7.2 取消订阅连接状态
       });
       this.gattServer.close() // 7.3 如果不再使用此gattServer,则需要close
     } catch (err) {
       console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
     }
    

    }
    }

    let gattServerManager = new GattServerManager();
    export default gattServerManager as GattServerManager;

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档 》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

总结

鸿蒙---作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

相关推荐
ZZZCY200330 分钟前
华为VER系统及CLI命令熟悉
华为
SameX1 小时前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
hzyyyyyyyu2 小时前
内网安全隧道搭建-ngrok-frp-nps-sapp
服务器·网络·安全
刽子手发艺2 小时前
WebSocket详解、WebSocket入门案例
网络·websocket·网络协议
速盾cdn6 小时前
速盾:CDN是否支持屏蔽IP?
网络·网络协议·tcp/ip
yaoxin5211236 小时前
第二十七章 TCP 客户端 服务器通信 - 连接管理
服务器·网络·tcp/ip
内核程序员kevin6 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
PersistJiao8 小时前
Spark 分布式计算中网络传输和序列化的关系(一)
大数据·网络·spark
Random_index9 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos