首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

鸿蒙软件+硬件+华为云操作手册

  • 25-03-08 01:22
  • 4591
  • 13258
blog.csdn.net

操作手册——软件篇

一、准备工作

  • Windows的Hyper-V功能开启

选择开始菜单,单击设置

选择系统->激活,查看自己的Windows版本是家庭版还是其它

Windows专业版开启Hyper-V功能

开启后,重启电脑,在搜索栏上搜索Hyper-V,看是否存在

Windows家庭版开启Hyper-V功能

1.打开记事本,将下面的代码复制到里面,然后另存为XX.bat,名字可以自定义

@echo off

Pushd "%~dp0"

dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt

for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"

del hyper-v.txt

Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL

pause

2.运行后,会在当前目录创建hyper.txt文件(可以删除),重启后,搜索Hyper是否存在,如果没有,那就可以使用专业版的方法启动该功能(家庭版默认该功能被隐藏)

参考文章:

Windows家庭版没有Hyper-V功能的解决方案_windows没有hyper-v-CSDN博客

  • 华为DevEco Studio安装手册

文档中心

注意:安装华为DevEco Studio时,一定要先启用Hyper-V功能,否则无法使用模拟器或者预览器

  • 硬件模拟测试软件

MQTTX

MQTTX:全功能 MQTT 客户端工具

二、华为云的使用

  • 华为云IoTDA的搭建

1.登录华为云

2.选择合适的服务区域

3.选择服务列表

4.搜索设备接入IoTDA服务

5.购买实例

6.按照图片所示进行自定义配置

7.确定配置无误后,选择提交

8.进入创建后的实例

9.创建设备之前,先记录一下后续操作需要使用的信息

10.MQTT接入地址是硬件或软件模拟上传数据的服务器地址,HTTPS接入地址是后续使用鸿蒙app进行云端数据获取或者命令下发的endpoint参数

11.选择产品

12.创建产品

13.按照图片所示进行自定义配置

14.所属行业与所属子行业可以随便选择模板,后续是通过自己的自定义模型来添加实际的数据属性和命令

15.选择详情进入产品详情页

16.添加自定义模型

17.自定义服务ID名,该ID也是后续鸿蒙app所使用的serviceid

18.根据自己的需求添加数据属性和命令

19.LedStatus是字符串类型,访问方式可读;命令LedSwitch,下发参数为value(字符串类型),响应参数result(布尔型),不同的命令的下发参数和响应参数可以一样,因为它们是通过命令名称进行区分的。注意: 数据类型要与硬件或者软件模拟的数据类型保存一致,否则会出现问题

20.进入Topic管理

21.记录一下设备ID就是后面所创建的云端设备

平台下发命令给设备:

$oc/devices/设备ID/sys/commands/response/request_id=

设备上报属性数据:

$oc/devices/设备ID/sys/properties/report

22.选择设备->所有设备

23.注册设备,添加云端设备

24.根据下面的图片进行自定义配置

25.保存并关闭后,浏览器会下载一个密钥文件,可以选择自己保存,也可以删除,因为设备详情页里面可以查看

26.进入设备详情页

27.根据图片,记录一下所需内容

  • 件或软件模拟测试硬

1.根据图片,将之前记录的相关信息填入到MQTTX软件中,硬件类似

2.连接成功后,云端设备会显示在线

3.使用$oc/devices/设备ID/sys/properties/report,将数据按照指定格式进行数据的上报。

参考文档:

设备属性上报_设备接入 IoTDA_华为云

4.上报成功后,云端会得到硬件或软件模拟的值

三、鸿蒙app的使用

1.先记录一下自己API凭证,这是后续鸿蒙app的project_id,项目ID

2.一般都是创建一个新的权限不高的IAM用户来获取XToken,在后续的鸿蒙app中用于获取XToken,只有经过验证后的XToken,才能让鸿蒙app获取云端数据或者下发命令

3.在创建的鸿蒙项目的ets目录下创建Tools目录和Models目录,然后在Tools创建一个HttpTool的ArkTS文件,在Models目录下创建一个HW_User的ArkTS文件(这是将常用的Http操作和IAM用户获取X-Token进行封装,方便后续操作)

HW_User.ets

export class HW_User {
  auth: Auth

  constructor(name: string, password: string, domain: string) {
    this.auth = {
      "identity": {
        "methods": [
          "password"
        ],
        "password": {
          "user": {
            "domain": {
              "name": domain        //IAM用户所属账号名
            },
            "name": name, //IAM用户名
            "password": password      //IAM用户密码
          }
        }
      },
      "scope": {
        "domain": {
          "name": domain       //IAM用户所属账号名
        }
      }
    }
  }
}

interface Auth {
  identity: Identity
  scope: Scope
}

interface Identity {
  methods: string[]
  password: Password
}

interface Password {
  user: User
}

interface User {
  name: string
  password: string
  domain: Domain
}

interface Domain {
  name: string
}

interface Scope {
  domain: Domain
}

结构是固定的,通过封装类来实现

参考文档:

获取IAM用户Token(使用密码)_统一身份认证服务 IAM_华为云

文档中的请求示例

HttpTool.ets

import { http } from '@kit.NetworkKit'

import { BusinessError } from '@kit.BasicServicesKit'

export class HttpTool {

  static get(url: string, fn: Function) {

    // 每一个httpRequest对应一个HTTP请求任务,不可复用

    let httpRequest = http.createHttp()

    let options: http.HttpRequestOptions = {

      method: http.RequestMethod.GET,

      // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定

      expectDataType: http.HttpDataType.OBJECT, // 可选,指定返回数据的类型

      // 开发者根据自身业务需要添加header字段

      // header: { 'Accept': 'application/json' },

      header: {

        'Content-Type': 'application/json',

        'X-Auth-Token': globalThis.token  //获取云端数据需要xToken认证,这里使用全局变量

      },

    }

    httpRequest.request(url, options, (err: BusinessError, data: http.HttpResponse) => {

      if (!err) {

        fn(data)

      } else {

        console.info('error:' + JSON.stringify(err))

      }

      httpRequest.destroy()

    })

  }

 //一般情况下的post请求

  static post(url: string, param: string | Object | ArrayBuffer, fn: Function) {

    // 每一个httpRequest对应一个HTTP请求任务,不可复用

    let httpRequest = http.createHttp()

    let options: http.HttpRequestOptions = {

      method: http.RequestMethod.POST,

      // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定

      extraData: param,

      expectDataType: http.HttpDataType.OBJECT, // 可选,指定返回数据的类型

      // 开发者根据自身业务需要添加header字段

      // header: { 'Accept': 'application/json' },

      header: {

        'Content-Type': 'application/json',

      },

    }

    httpRequest.request(url, options, (err: BusinessError, data: http.HttpResponse) => {

      if (!err) {

        fn(data)

      } else {

        console.info('error:' + JSON.stringify(err))

      }

      httpRequest.destroy()

    })

  }

  //命令下发使用的post请求

  static postCommands(url: string, param: string | Object | ArrayBuffer, fn: Function) {

    // 每一个httpRequest对应一个HTTP请求任务,不可复用

    let httpRequest = http.createHttp()

    let options: http.HttpRequestOptions = {

      method: http.RequestMethod.POST,

      // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定

      extraData: param,

      expectDataType: http.HttpDataType.OBJECT, // 可选,指定返回数据的类型

      // 开发者根据自身业务需要添加header字段

      // header: { 'Accept': 'application/json' },

      header: {

        'Content-Type': 'application/json',

        'X-Auth-Token': globalThis.token //下发命令需要xToken认证,这里使用全局变量

      },

    }

    httpRequest.request(url, options, (err: BusinessError, data: http.HttpResponse) => {

      if (!err) {

        fn(data)

      } else {

        console.info('error:' + JSON.stringify(err))

      }

      httpRequest.destroy()

    })

  }

}

参考文档:

文档中心

Index.ets

import { HW_User } from '../Models/HW_User'

import { HttpTool } from '../Tools/HttpTool'

import { http } from '@kit.NetworkKit'

//通过接口的封装来下达命令和接受返回参数

interface Command {

  service_id: string

  command_name: string

  paras: Paras

}

interface Paras {

  value: string

}

interface Properties {

  LedStatus: string

}

// Command和Paras使用接口来实现命令下发的上传格式,Properties是使用接口获取云端数据的返回数据

@Entry

@Component

struct Index {

  private url: string = 'https://iam.myhuaweicloud.com/v3/auth/tokens'

  private hw_user = new HW_User('你创建的IAM用户', '你的IAM用户密码', '你的登录或注册的默认用户就是domain')

  // 使用封装的HW_User来进行用户的认证,从左往右依次是新创建的IAM用户及其密码,还有你的默认用户企业管理员

  private endpoint: string = '你的http接入地址'

  private project_id: string = '你的api凭证也就是项目id'

  private device_id: string = '你的设备id'

  //endpoint是你之前复制的https接入地址,project_id是你复制的api凭证(要与区域保持一致),device_id是你的设备id

  private url1: string =

    'https://' + this.endpoint + '/v5/iot/' + this.project_id + '/devices/' + this.device_id + '/shadow'

  private url2: string =

    'https://' + this.endpoint + '/v5/iot/' + this.project_id + '/devices/' + this.device_id + '/commands'

  //url1是获取云端数据的写法,url2是命令下发的写法

  @State properties: Properties = { LedStatus: '' }

  private com: Command = { service_id: 'TS001', command_name: 'LedSwitch', paras: { 'value': 'ON' } }

 //使用接口重载可以方便后续的调整

  build() {

    Column() {

      Column() {

        //onClick事件,当单击文本时,触发里面所写的内容

        Text('获取Token').fontSize(25).onClick(() => {

          HttpTool.post(this.url, this.hw_user, (data: http.HttpResponse) => {

            console.log('result:', JSON.stringify(data.result))

            globalThis.token = data.header['x-subject-token'] //x-subject-token作为全局变量,让封装的HttpTool类可以使用

          })

          // 使用封装类后的HttpTool的post请求获取到x-token的值

        })

        Text('获取数据').fontSize(25).onClick(() => {

          HttpTool.get(this.url1, (data: http.HttpResponse) => {

            console.log('result:', JSON.stringify(data.result)) //打印获取的结果到终端上

            this.properties = data.result['shadow'][0].reported.properties as Properties

            console.log('LedStatus:' + this.properties.LedStatus) //将获取到的LedStatus打印到终端上

          })

        })

        Text('命令下发测试').fontSize(25).onClick(() => {

          HttpTool.postCommands(this.url2, this.com, (data: http.HttpResponse) => {

            console.log('result:', JSON.stringify(data.result))//将获取到的命令返回结果打印到终端上

          })

        })

      }

    }.width('100%').height('100%')

  }

}

数据获取参考文档

查询设备影子数据_设备接入 IoTDA_华为云

命令下发参考文档

下发设备命令_设备接入 IoTDA_华为云

4.代码写好后,启动预览器或者模拟器,然后打开日志调试终端,进行测试

软件模拟或硬件做出命令回应的格式参考文档

平台命令下发_设备接入 IoTDA_华为云

软件模拟或硬件上传数据的格式参考文档

设备属性上报_设备接入 IoTDA_华为云

至此,有关鸿蒙app连接华为云获取硬件上传的数据和下发命令的操作教程结束,至于本地服务端的搭建,因每个人所使用的web框架和数据库不一样,这里不在写了。简单来说就是web框架连接数据库,从数据库获取数据,然后使用鸿蒙app的post请求获取web框架的页面路由返回数据,就可以将数据读取到鸿蒙app中。

鸿蒙的ArkTS语言学习参考文档:

官方文档:

文档中心-HarmonyOS NEXT开发文档-华为开发者联盟

官方免费的视频教程:

华为开发者学堂

或者其它平台的学习资源

操作手册——硬件篇

  • 一、OpenHarmony硬件开发环境配置

声明:提供的资料文件有

hi3861_hdu_iot_application240515

DevTools_Hi3861V100_v1.0.zip

CH341SER.EXE

串口调试助手

(一)、安装 Visual Studio Code

1.下载VSCode

VSCode全称是Visual Studio Code,它是一款免费开源的现代化轻量级代码编辑器。VSCode官方下载地址是:Visual Studio Code - Code Editing. Redefined我们使用Windows x64 版本

具体安装步骤参考VSCode安装配置使用教程(最新版超详细保姆级含插件)一文就够了_vscode使用教程-CSDN博客

2.安装VSCode相关插件

安装完VSCode后,需要安装如下图的插件:

以C/C++插件安装为例,点击左侧的扩展商店里输入“C/C++”,选择下载第一个

其余插件安装步骤相似,最终安装结果显示如下:

  1. 安装DevEco Device Tool

HUAWEI DevEco Device Tool(以下简称DevEco Device Tool)是HarmonyOS面向智能设备开发者提供的一站式集成开发环境,支持HarmonyOS的组件按需定制,支持代码编辑、编译、烧录和调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。

  1. 打开HarmonyOS官网开发工具网站:华为集成开发环境IDE DevEco Device Tool下载 | HarmonyOS设备开发

找到“DevEco Device Tool 4.0 Release”

  1. 在控制面板-添加或删除程序中,搜索Python关键字,遭到所有安装的Python进行卸载,特别是安装Anconda环境下的Python,避免干扰环境,确保在cmd中输入python后系统找不到python环境即可。

  1. 双击DevEco Device Tool安装包程序,点击“Next”,进行安装。
  2. 设置安装路径,点击“Next”。

  1. 第2)步中已经卸载Python,所以选择“自定义安装”(注意选择Add Python 3.8 to PATH),然后点击Install Now。安装完成后点击Close即可。

选择添加PATH选项

注意 Python 必须安装在全英文目录!如果默认目录不是全英文目录,需要点击 Customize install ation 选项:

然后点击 Next:

勾选 Install for all users 和 Add Python to environment variables,从而保证英文安装目录并添加环境变量。

在界面中点击“安装”进行软件安装。

安装成功后打开VSCode后扩展览显示这四个扩展:

4.启动DevEco Device Tool

1)启用VSCode,在DevEco Device Tool运行时依赖C/C++、CodeLLDB插件,可以在VSCode的扩展包管理处进行搜索和安装。

  1. 重启VSCode软件,点击左侧扩展列表,即可打开DevEco Home界面,表示成功安装开发环境。

5.下载SDK

我会将SDK压缩包提供出来

我们的例程代码位于目录【\\hi3861_hdu_iot_application\src\vendor\hqyj\fs_hi3861\demo】面,可通过编辑【\\hi3861_hdu_iot_application\src\applications\sample\wifi-iot\app\BUILD.gn】中的信息来将编译目录指向我们的例程,如下图所示:

  1. 开发工具下载

1)我将提供DevTools_Hi3861V100_v1.0.zip包,注意解压到全英文目录下,解压后的目录文件结构如下:

2)打开VSCode,打开DevEco Device Tool主页,点击“导入工程”。

3)在导入工程弹窗中选择Hi3861 SDK目录,点击“导入”。

4)在后续导入工程弹窗,SOC栏选择Hi3861,开发板栏选择hi3861,框架栏选择hb,之后点击“导入”,等待导入成功即可。

  1. 代码导入成功后,即工程创建成功,之后可使用该IDE 实现代码开发、一键编译、一键烧写等功能。

7)配置开发工具路径,点击左侧的“工程配置”,选中“请选择自定义工具包”(有的版本可能无此界面,直接进行下一步即可)。

8)然后在右侧窗口中找到“hi3861,”找到“compiler_bin_path”,选择到之前下载的开发工具。

  1. 配置产品

注意:以下步骤已经在所给文件中配置完成,不用手动配置,后期更改编译文件时在选择性地配置。

1)在src/applications/sample/wifi-iot/BUILD.gn文件中,修改features,如下所示。该路径用于指示编译系统去哪里寻找需要编译的组件。其中冒号前的demo指的是文件所在的目录,冒号后的demo 指的是该目录下的BUILD.gn文件中的哪个lite_component。

2).修改vendor/hqyj/fs_hi3861/demo/BUILD.gn,根据需要编译对应的示例程序:

3)由于编译过程中涉及到部分板级的驱动,因此需要复制光盘资料里的硬件驱动代码到hi3861_hdu_iot_application\src\vendor\hqyj\fs_hi3861\common\bsp目录,并且在程序里引入相应文件时保证该工程下的BUILD.gn文件里面包含了相应的路径。我们提供的工程文件已做好这些内容,因此不用再次操作。

  1. 编译工程

1)配置完成后,点击左侧“Rebuild”,开始编译。

2)初次编译会解压编译工具,时间较长。等待编译完成即可。

  1. 代码烧录
  1. 串口驱动安装

1.先使用配套的Type-C数据线,将开发板与电脑的USB口进行连接。

2.安装CH340G驱动。安装CH341SER.EXE文件。

双击CH341SER.EXE驱动,进入安装界面,点击安装按钮即可,驱动安装成功后,再点击确定按钮,即可显示安装驱动成功。

  1. 打开Windows的设备管理器,查看串口设备,若未出现CH340串口设备,请检查驱动是否安装正常。

  1. 串口烧录
  1. 当前DevEco Device Tool工具支持Hi3861单板一键烧录功能。需要连接开发板,配置开发板对应的串口,在编译结束后,进行烧录。点击左侧“工程配置”,找到“upload_port”选项,选择开发板对应的烧录串口(注意:如果正在使用Monitor功能,请先关闭Monitor,才能正常烧,否则串口占用无法烧录成功)。

2.打开开发板左下角的电源S1。

3.点击VSCode左下角“upload”按键,等待提示(出现Connecting,please reset device...),手动进行开发板复位(按下开发板复位按键)。

4.等待烧录完成,大约30s左右,烧录成功。

10.串口打印

1)烧录完成后,可以通过Monitor界面查看串口打印,配置Monitor串口,如下图所示。

2)配置完Monitor串口后,直接点击monitor按钮,复位开发板,查看开发板端的打印信息。

查看串口信息也可用串口调试助手(UartAssist)进行。注意,如果使用中文,需要选择好编码集。

智能农业的项目实操

  1. 修改文件

对C:\hi3861_hdu_iot_application\src\vendor\hqyj\fs_hi3861\common\bsp\include\hal_bsp_ssd1306_bmps.h路径下的文件进行

#define smartFarm 0 

修改成

#define smartFarm 1

修改

C:\hi3861_hdu_iot_application\src\vendor\hqyj\fs_hi3861\demo\BUILD.gn文件中

的 "smartFarm:smartFarm_demo",将注释的#号去掉

进入我们已经注册过的阿里云物联网平台中,点击进入设备接入ioTDA。

点击试用进入控制台

点击进入iot实例

点击设备—所有设备


进入后可以看到我们在上面已经创建过的设备

点击详情操作页面

找到mqtt连接参数,点击查看

可以查看连接mqtt所需要的参数

回到vccode中

在我们的代码中找到smartfarm的项目文件夹,代码的路径

C:\hi3861_hdu_iot_application\src\vendor\hqyj\fs_hi3861\demo\smartFarm

打开项目中的sys_config.h文件

点击进入配置代码

将mqtt的连接参数复制到代码中,需要注意一一对应且端口号是1883并非是8883.

修改华为云平台的MQTT服务器的IP地址,打开Windows下cmd控制端,在控制端输入内容。

将这个ip地址填入代码中

填入mqtt信息

回到华为云平台iot实例,点击产品

点击详情

进入模型定义界面,点击编辑

添加基础服务(base)

添加控制服务(control)

在基础服务(base)中添加“fan”属性

在基础服务(base)中添加“humidity”属性

在基础服务(base)中添加temperature”属性

在基础服务(base)中添”automode’属性

在控制服务(control)中添加“fan”命令

在控制服务(control)中添加“automode”命令

回到demo代码中,进入

C:\hi3861_hdu_iot_application\src\vendor\hqyj\fs_hi3861\common\bsp\src\hal_bsp_nfc_to_wifi.c文件将上面部分注释掉

并添加这串代码

uint8_t wechat_GetWiFi_ssid_passwd(const char *nfc_buff, char *wifi_name,char *wifi_passwd)

{

    uint8_t payload_len = nfc_buff[NDEF_PROTOCOL_DATA_LENGTH_OFFSET]; // 获取数据长度

    //uint8_t payload_len = nfc_buff[2]; // 获取数据长度

    uint8_t *payload = (uint8_t *)malloc(payload_len + 1);

    uint8_t ret = 0;

    if (payload == NULL) {

        printf("payload malloc failed.\r\n");

        return 0;

    }

    memset_s(payload, payload_len + 1, 0, payload_len + 1);

    //memcpy_s(payload, payload_len + 1, nfc_buff + NDEF_PROTOCOL_VALID_DATA_OFFSET, payload_len);

    memcpy_s(payload, payload_len + 1, nfc_buff + 9, payload_len);

    printf("Use Wechat system..........\n");

    printf("payload = %s\r\n", payload);

    cJSON *root = cJSON_Parse(payload);

    cJSON *ssid = cJSON_GetObjectItem(root, "ssid");

    cJSON *password = cJSON_GetObjectItem(root, "passwd");

    if (root != NULL && ssid != NULL && password != NULL) {

        printf("ssid = %s, password = %s", ssid->valuestring, password->valuestring);

        if (strcpy_s(wifi_name, strlen(ssid->valuestring) + 1, ssid->valuestring) == 0) {

            ret = 1;

        } else {

            ret = 0;

        }

        if (strcpy_s(wifi_passwd, strlen(password->valuestring) + 1, password->valuestring) == 0) {

            ret = 1; // 成功获取到WiFi名称和密码

        } else {

            ret = 0;

        }

    cJSON_Delete(root);

    free(payload);

    ssid = NULL;

    password = NULL;

    root = NULL;

    payload = NULL;

    return ret;

}

}

uint32_t NFC_configuresWiFiNetwork(uint16_t *ndefBuff)

{

   

    if (ndefBuff == NULL) {

        printf("NFC_configuresWiFiNetwork to ndefBuff is NULL\r\n");

        return -1;

    }

    uint8_t ret = 0;

    char *  wifi_name[MAX_BUFF] = {0}; // WiFi名称

    char *  wifi_passwd[MAX_BUFF] = {0}; // WiFi密码

    //使用微信小程序进行配网

    #if 0

    if (ndefBuff[NDEF_PROTOCOL_DATA_TYPE_OFFSET] == 't') {

        ret = wechat_GetWiFi_ssid_passwd(ndefBuff, wifi_name, wifi_passwd);

    } else {

        ret = ios_GetWiFi_ssid_passwd(ndefBuff, wifi_name, wifi_passwd);

     }

     #endif

     ret = wechat_GetWiFi_ssid_passwd(ndefBuff, wifi_name, wifi_passwd);

    if (ret)

   

   

        //char *wifi_name = "peigezhao";

        //char *wifi_passwd = "peigezhao";

        printf("wifi_name: %s\n", wifi_name);

        printf("wifi_passwd: %s\n", wifi_passwd);

 

        // 连接wifi

        if (WIFI_SUCCESS == WiFi_connectHotspots(wifi_name, wifi_passwd)) {

            printf("thongth to nfc connect wifi is success.\r\n");

            ret= 0;

        } else {

            printf("thongth to nfc connect wifi is failed.\r\n");

            ret=1;

        }

       return ret;

}

对修改的代码进行编译

编译如果出现succes的绿色字体证明编译成功

点击烧录按钮,需要检测端口号是否正确

手机下载nfc标签助手

、

点击进入软件进行nfc配网

点击文本

在里面以josn的格式输入自己的wifi名和wifi密码

写入后靠近hi3861开发板,重启开发板即可配网成功

重启后可观察到开发版的实际效果

注:本文转载自blog.csdn.net的真的啥也不会呀的文章"https://blog.csdn.net/m0_74245417/article/details/144232033"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

135
HarmonyOS
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top