鸿蒙App分布式软总线设备列表展示(手机/平板/电视)详解
【摘要】 引言分布式软总线是鸿蒙系统的核心技术之一,它实现了多设备间的自动发现和通信,如同在同一设备上运行一样。在分布式应用场景中,设备列表展示是第一步,用户需要看到可用的设备并进行选择以建立连接。本文将详细介绍如何在鸿蒙应用中实现分布式软总线的设备发现与列表展示,支持手机、平板、电视等多种设备类型。技术背景分布式软总线概述分布式软总线是鸿蒙系统实现分布式能力的基础设施,它提供了设备自动发现、连接管理...
引言
技术背景
分布式软总线概述
-
自动发现:设备在近距离内自动发现彼此 -
动态组网:设备间形成对等网络 -
弹性扩展:支持1+8+N设备协同 -
低时延:毫秒级延迟的跨设备通信
设备发现机制
-
广播阶段:设备周期性发送广播包 -
扫描阶段:设备监听并解析广播包
设备类型标识
-
Phone(手机) -
Tablet(平板) -
TV(电视) -
Car(车机) -
Wearable(穿戴设备)
应用使用场景
-
多屏协同:手机与平板、电视等设备协同办公 -
分布式游戏:多设备协同的游戏体验 -
媒体投屏:将手机上的视频投到电视播放 -
文件互传:设备间快速传输文件 -
智能家居控制:手机作为控制中心管理其他设备
不同场景下详细代码实现
场景1:基础设备发现与列表展示
// DeviceDiscoveryManager.java
package com.example.distributeddemo;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.rpc.RemoteException;
import java.util.ArrayList;
import java.util.List;
public class DeviceDiscoveryManager {
private static final String TAG = "DeviceDiscoveryManager";
private List<DeviceInfo> deviceList = new ArrayList<>();
private EventHandler handler;
private Ability ability;
private DeviceListUpdateListener listener;
public interface DeviceListUpdateListener {
void onDeviceListUpdated(List<DeviceInfo> devices);
}
public DeviceDiscoveryManager(Ability ability) {
this.ability = ability;
this.handler = new EventHandler(EventRunner.current()) {
@Override
protected void processEvent(InnerEvent event) {
super.processEvent(event);
if (event.eventId == 1 && listener != null) {
listener.onDeviceListUpdated((List<DeviceInfo>) event.object);
}
}
};
}
public void setDeviceListUpdateListener(DeviceListUpdateListener listener) {
this.listener = listener;
}
public void startDeviceDiscovery() {
DeviceManager.DeviceStateCallback callback = new DeviceManager.DeviceStateCallback() {
@Override
public void onDeviceFound(DeviceInfo deviceInfo) {
if (!deviceList.contains(deviceInfo)) {
deviceList.add(deviceInfo);
notifyDeviceListUpdated();
}
}
@Override
public void onDeviceDisconnected(String deviceId) {
deviceList.removeIf(device -> device.getDeviceId().equals(deviceId));
notifyDeviceListUpdated();
}
};
try {
DeviceManager.registerDeviceStateCallback(callback);
List<DeviceInfo> onlineDevices = DeviceManager.getOnlineDeviceList();
deviceList.clear();
deviceList.addAll(onlineDevices);
notifyDeviceListUpdated();
} catch (RemoteException e) {
Log.error(TAG, "设备发现失败: " + e.getMessage());
}
}
public void stopDeviceDiscovery() {
try {
DeviceManager.unregisterDeviceStateCallback();
} catch (RemoteException e) {
Log.error(TAG, "停止设备发现失败: " + e.getMessage());
}
}
private void notifyDeviceListUpdated() {
InnerEvent event = InnerEvent.get(1, new ArrayList<>(deviceList));
handler.postTask(() -> handler.sendEvent(event));
}
public List<DeviceInfo> getDeviceList() {
return new ArrayList<>(deviceList);
}
}
场景2:按设备类型过滤展示
// DeviceFilter.java
package com.example.distributeddemo;
import ohos.distributedschedule.interwork.DeviceInfo;
import java.util.ArrayList;
import java.util.List;
public class DeviceFilter {
public static final int DEVICE_TYPE_PHONE = 0;
public static final int DEVICE_TYPE_TABLET = 1;
public static final int DEVICE_TYPE_TV = 2;
public static final int DEVICE_TYPE_CAR = 3;
public static final int DEVICE_TYPE_WEARABLE = 4;
public static List<DeviceInfo> filterByDeviceType(List<DeviceInfo> devices, int deviceType) {
List<DeviceInfo> filteredDevices = new ArrayList<>();
for (DeviceInfo device : devices) {
if (getDeviceType(device) == deviceType) {
filteredDevices.add(device);
}
}
return filteredDevices;
}
public static int getDeviceType(DeviceInfo device) {
String deviceType = device.getDeviceType();
if (deviceType.equals("PHONE")) {
return DEVICE_TYPE_PHONE;
} else if (deviceType.equals("TABLET")) {
return DEVICE_TYPE_TABLET;
} else if (deviceType.equals("TV")) {
return DEVICE_TYPE_TV;
} else if (deviceType.equals("CAR")) {
return DEVICE_TYPE_CAR;
} else if (deviceType.equals("WEARABLE")) {
return DEVICE_TYPE_WEARABLE;
}
return -1; // Unknown
}
public static String getDeviceTypeName(int deviceType) {
switch (deviceType) {
case DEVICE_TYPE_PHONE: return "手机";
case DEVICE_TYPE_TABLET: return "平板";
case DEVICE_TYPE_TV: return "电视";
case DEVICE_TYPE_CAR: return "车机";
case DEVICE_TYPE_WEARABLE: return "穿戴设备";
default: return "未知设备";
}
}
}
场景3:设备列表UI展示
// DeviceListAbilitySlice.java
package com.example.distributeddemo;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.distributedschedule.interwork.DeviceInfo;
import java.util.List;
public class DeviceListAbilitySlice extends AbilitySlice {
private ListContainer listContainer;
private Button refreshButton;
private Text titleText;
private SegmentedBar segmentedBar;
private DeviceDiscoveryManager discoveryManager;
private DeviceListAdapter adapter;
private int currentFilter = DeviceFilter.DEVICE_TYPE_PHONE;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_device_list);
initUIComponents();
setupSegmentedBar();
setupDeviceDiscovery();
setupRefreshButton();
}
private void initUIComponents() {
listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
refreshButton = (Button) findComponentById(ResourceTable.Id_refresh_btn);
titleText = (Text) findComponentById(ResourceTable.Id_title_text);
segmentedBar = (SegmentedBar) findComponentById(ResourceTable.Id_segmented_bar);
}
private void setupSegmentedBar() {
String[] segments = {"手机", "平板", "电视", "全部"};
segmentedBar.setSegmentCount(segments.length);
for (int i = 0; i < segments.length; i++) {
segmentedBar.setSegmentText(i, segments[i]);
}
segmentedBar.setSelectedIndex(0);
segmentedBar.setSelectedListener(index -> {
currentFilter = index == 3 ? -1 : index;
updateDeviceList();
});
}
private void setupDeviceDiscovery() {
discoveryManager = new DeviceDiscoveryManager(this);
discoveryManager.setDeviceListUpdateListener(devices -> {
getUITaskDispatcher().asyncDispatch(() -> {
updateDeviceList();
});
});
discoveryManager.startDeviceDiscovery();
}
private void setupRefreshButton() {
refreshButton.setClickedListener(component -> {
titleText.setText("正在搜索设备...");
discoveryManager.stopDeviceDiscovery();
discoveryManager.startDeviceDiscovery();
});
}
private void updateDeviceList() {
List<DeviceInfo> allDevices = discoveryManager.getDeviceList();
List<DeviceInfo> filteredDevices;
if (currentFilter == -1) {
filteredDevices = allDevices;
} else {
filteredDevices = DeviceFilter.filterByDeviceType(allDevices, currentFilter);
}
if (adapter == null) {
adapter = new DeviceListAdapter(this, filteredDevices);
listContainer.setItemProvider(adapter);
} else {
adapter.setDeviceList(filteredDevices);
adapter.notifyDataChanged();
}
titleText.setText("可用设备列表 (" + filteredDevices.size() + ")");
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
原理解释
设备发现流程
-
设备上线:设备连接到网络后,向软总线服务注册 -
广播发现:设备周期性发送包含自身信息的广播包 -
扫描接收:其他设备监听并解析广播包 -
状态维护:维护一个在线设备列表,实时更新设备状态
设备连接建立
sequenceDiagram
participant A as 设备A
participant S as 软总线服务
participant B as 设备B
A->>S: 1. 发现设备B
S->>A: 2. 返回设备B信息
A->>B: 3. 发送连接请求
B->>A: 4. 接受连接
A->>S: 5. 注册连接会话
B->>S: 6. 注册连接会话
S->>A,B: 7. 确认连接建立
核心特性
-
自动发现:无需手动配置,自动发现附近设备 -
多设备支持:支持手机、平板、电视等多种设备 -
实时更新:设备状态变化时实时更新列表 -
类型过滤:可按设备类型筛选展示 -
连接管理:提供设备连接状态管理 -
安全认证:设备间通信经过安全认证
原理流程图及解释
设备发现与展示流程
graph TD
A[应用启动] --> B[初始化DeviceManager]
B --> C[注册设备状态回调]
C --> D[开始设备发现]
D --> E[接收设备发现事件]
E --> F[更新设备列表]
F --> G[刷新UI展示]
G --> H[用户选择设备]
H --> I[建立设备连接]
-
应用启动时初始化设备管理器 -
注册设备状态回调函数 -
开始设备发现过程 -
接收设备发现事件(新设备上线、设备下线) -
更新内部维护的设备列表 -
刷新UI展示最新设备列表 -
用户从列表中选择设备进行连接 -
建立与选定设备的连接
环境准备
开发环境要求
-
操作系统:Windows 10/11 或 macOS 10.15+ -
开发工具:DevEco Studio 3.0+ -
SDK版本:API Version 6+(HarmonyOS 2.0+) -
设备要求:HarmonyOS 2.0+真机或模拟器 -
语言支持:Java/JS(推荐Java)
配置步骤
-
安装DevEco Studio: -
从华为开发者官网下载安装包 -
按照向导完成安装 -
配置HarmonyOS SDK路径
-
-
创建新项目: File > New > New Project Select "Application" > "Empty Ability" Set project name: DistributedDeviceDemo Set compatible API version: 6 -
添加权限配置: 在 config.json中添加分布式权限:{ "module": { "reqPermissions": [ { "name": "ohos.permission.DISTRIBUTED_DATASYNC", "reason": "Discover and connect distributed devices" }, { "name": "ohos.permission.READ_USER_STORAGE", "reason": "Read device information" } ] } }
实际详细应用代码示例实现
主界面布局(XML)
<!-- resources/base/layout/ability_device_list.xml -->
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical">
<Text
ohos:id="$+id:title_text"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="可用设备列表"
ohos:text_size="32fp"
ohos:text_alignment="center"
ohos:layout_alignment="horizontal_center"
ohos:top_margin="20"/>
<SegmentedBar
ohos:id="$+id:segmented_bar"
ohos:width="match_parent"
ohos:height="40vp"
ohos:top_margin="10"
ohos:background_element="#F0F0F0"/>
<ListContainer
ohos:id="$+id:list_container"
ohos:width="match_parent"
ohos:height="0vp"
ohos:weight="1"
ohos:top_margin="20"
ohos:bottom_margin="20"/>
<Button
ohos:id="$+id:refresh_btn"
ohos:width="match_parent"
ohos:height="60vp"
ohos:text="刷新设备列表"
ohos:text_size="20fp"
ohos:background_element="#007DFF"
ohos:text_color="white"
ohos:top_margin="20"/>
</DirectionalLayout>
设备列表项布局(XML)
<!-- resources/base/layout/item_device.xml -->
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="80vp"
ohos:orientation="horizontal"
ohos:padding="10">
<Image
ohos:id="$+id:device_icon"
ohos:width="60vp"
ohos:height="60vp"
ohos:image_src="$media:ic_device_phone"
ohos:scale_mode="stretch"/>
<DirectionalLayout
ohos:width="0vp"
ohos:height="match_parent"
ohos:weight="1"
ohos:margin="10">
<Text
ohos:id="$+id:device_name"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="设备名称"
ohos:text_size="20fp"
ohos:text_weight="700"/>
<Text
ohos:id="$+id:device_id"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="设备ID"
ohos:text_size="16fp"
ohos:text_color="gray"/>
</DirectionalLayout>
<Text
ohos:id="$+id:device_status"
ohos:width="80vp"
ohos:height="match_content"
ohos:text="在线"
ohos:text_size="18fp"
ohos:text_color="green"/>
</DirectionalLayout>
设备列表适配器
// DeviceListAdapter.java
package com.example.distributeddemo;
import ohos.agp.components.*;
import ohos.distributedschedule.interwork.DeviceInfo;
import java.util.List;
public class DeviceListAdapter extends BaseItemProvider {
private List<DeviceInfo> deviceList;
private AbilitySlice slice;
public DeviceListAdapter(AbilitySlice slice, List<DeviceInfo> deviceList) {
this.slice = slice;
this.deviceList = deviceList;
}
public void setDeviceList(List<DeviceInfo> deviceList) {
this.deviceList = deviceList;
}
@Override
public int getCount() {
return deviceList == null ? 0 : deviceList.size();
}
@Override
public Object getItem(int position) {
return deviceList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Component getComponent(int position, Component convertComponent, ComponentContainer parent) {
Component component = convertComponent;
if (component == null) {
component = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_device, parent, false);
}
DeviceInfo device = deviceList.get(position);
((Text) component.findComponentById(ResourceTable.Id_device_name)).setText(device.getDeviceName());
((Text) component.findComponentById(ResourceTable.Id_device_id)).setText(device.getDeviceId());
Image icon = (Image) component.findComponentById(ResourceTable.Id_device_icon);
switch (DeviceFilter.getDeviceType(device)) {
case DeviceFilter.DEVICE_TYPE_PHONE:
icon.setPixelMap(ResourceTable.Media_ic_device_phone);
break;
case DeviceFilter.DEVICE_TYPE_TABLET:
icon.setPixelMap(ResourceTable.Media_ic_device_tablet);
break;
case DeviceFilter.DEVICE_TYPE_TV:
icon.setPixelMap(ResourceTable.Media_ic_device_tv);
break;
case DeviceFilter.DEVICE_TYPE_CAR:
icon.setPixelMap(ResourceTable.Media_ic_device_car);
break;
case DeviceFilter.DEVICE_TYPE_WEARABLE:
icon.setPixelMap(ResourceTable.Media_ic_device_wearable);
break;
default:
icon.setPixelMap(ResourceTable.Media_ic_device_unknown);
}
return component;
}
}
主AbilitySlice实现
// DeviceListAbilitySlice.java
package com.example.distributeddemo;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.distributedschedule.interwork.DeviceInfo;
import java.util.List;
public class DeviceListAbilitySlice extends AbilitySlice {
private ListContainer listContainer;
private Button refreshButton;
private Text titleText;
private SegmentedBar segmentedBar;
private DeviceDiscoveryManager discoveryManager;
private DeviceListAdapter adapter;
private int currentFilter = DeviceFilter.DEVICE_TYPE_PHONE;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_device_list);
initUIComponents();
setupSegmentedBar();
setupDeviceDiscovery();
setupRefreshButton();
}
private void initUIComponents() {
listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
refreshButton = (Button) findComponentById(ResourceTable.Id_refresh_btn);
titleText = (Text) findComponentById(ResourceTable.Id_title_text);
segmentedBar = (SegmentedBar) findComponentById(ResourceTable.Id_segmented_bar);
}
private void setupSegmentedBar() {
String[] segments = {"手机", "平板", "电视", "全部"};
segmentedBar.setSegmentCount(segments.length);
for (int i = 0; i < segments.length; i++) {
segmentedBar.setSegmentText(i, segments[i]);
}
segmentedBar.setSelectedIndex(0);
segmentedBar.setSelectedListener(index -> {
currentFilter = index == 3 ? -1 : index;
updateDeviceList();
});
}
private void setupDeviceDiscovery() {
discoveryManager = new DeviceDiscoveryManager(this);
discoveryManager.setDeviceListUpdateListener(devices -> {
getUITaskDispatcher().asyncDispatch(() -> {
updateDeviceList();
});
});
discoveryManager.startDeviceDiscovery();
}
private void setupRefreshButton() {
refreshButton.setClickedListener(component -> {
titleText.setText("正在搜索设备...");
discoveryManager.stopDeviceDiscovery();
discoveryManager.startDeviceDiscovery();
});
}
private void updateDeviceList() {
List<DeviceInfo> allDevices = discoveryManager.getDeviceList();
List<DeviceInfo> filteredDevices;
if (currentFilter == -1) {
filteredDevices = allDevices;
} else {
filteredDevices = DeviceFilter.filterByDeviceType(allDevices, currentFilter);
}
if (adapter == null) {
adapter = new DeviceListAdapter(this, filteredDevices);
listContainer.setItemProvider(adapter);
} else {
adapter.setDeviceList(filteredDevices);
adapter.notifyDataChanged();
}
titleText.setText("可用设备列表 (" + filteredDevices.size() + ")");
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
运行结果
初始界面
可用设备列表 (0)
[手机][平板][电视][全部]
[刷新设备列表按钮]
(列表为空)
设备发现后界面
可用设备列表 (3)
[手机][平板][电视][全部] (选中"手机")
[List Item 1]
图标: 手机图标
名称: HUAWEI P40
ID: 123456789
状态: 在线
[List Item 2]
图标: 平板图标
名称: HUAWEI MatePad
ID: 987654321
状态: 在线
[List Item 3]
图标: 电视图标
名称: HUAWEI Vision
ID: 246813579
状态: 在线
测试步骤以及详细代码
测试步骤
-
创建HarmonyOS工程并添加上述代码 -
配置所需权限和资源文件 -
准备至少两台HarmonyOS设备(或模拟器) -
运行应用程序 -
观察设备列表是否自动发现并显示附近设备 -
测试刷新按钮功能 -
验证不同设备类型的图标显示
自动化测试代码
// DeviceDiscoveryTest.java
package com.example.distributeddemo.test;
import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
import ohos.aafwk.ability.delegation.AbilityDelegator;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class DeviceDiscoveryTest {
private AbilityDelegator abilityDelegator;
private DeviceDiscoveryManager discoveryManager;
@Before
public void setUp() {
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
discoveryManager = new DeviceDiscoveryManager(null); // 传入null仅用于测试
}
@Test
public void testDeviceDiscovery() {
// 模拟设备发现
DeviceInfo mockDevice = new DeviceInfo();
mockDevice.setDeviceName("Mock Device");
mockDevice.setDeviceId("mock_device_id");
mockDevice.setDeviceType("PHONE");
// 触发设备发现回调
discoveryManager.onDeviceFound(mockDevice);
// 验证设备列表是否包含新设备
List<DeviceInfo> devices = discoveryManager.getDeviceList();
assertEquals(1, devices.size());
assertEquals("Mock Device", devices.get(0).getDeviceName());
}
@Test
public void testDeviceDisconnection() {
// 先添加一个设备
DeviceInfo mockDevice = new DeviceInfo();
mockDevice.setDeviceId("mock_device_id");
mockDevice.setDeviceType("PHONE");
discoveryManager.onDeviceFound(mockDevice);
// 模拟设备断开
discoveryManager.onDeviceDisconnected("mock_device_id");
// 验证设备列表是否为空
assertTrue(discoveryManager.getDeviceList().isEmpty());
}
}
部署场景
-
多设备协同办公:手机、平板、笔记本协同 -
智慧家居:手机控制电视、音箱、家电 -
车载系统:手机与车机互联 -
教育培训:教师机与学生平板互动 -
企业展示:手机与大屏协同演示
疑难解答
问题1:无法发现设备
-
设备未登录同一华为账号 -
设备未开启分布式协同开关 -
设备不在同一局域网
// 检查分布式协同开关状态
boolean isEnabled = DeviceManager.isDistributedNetworkEnabled();
if (!isEnabled) {
// 引导用户开启分布式协同
Intent intent = new Intent();
intent.setAction(Settings.ACTION_DISTRIBUTED_NETWORK_SETTINGS);
startActivity(intent);
}
// 检查华为账号登录状态
AccountManager accountManager = AccountManager.getService();
if (!accountManager.isHuaweiAccountSignedIn()) {
// 引导用户登录华为账号
Intent intent = new Intent();
intent.setAction(Settings.ACTION_ADD_ACCOUNT);
startActivity(intent);
}
问题2:设备列表更新不及时
-
设备状态回调未正确注册 -
事件处理线程阻塞
// 确保在UI线程更新列表
discoveryManager.setDeviceListUpdateListener(devices -> {
getUITaskDispatcher().asyncDispatch(() -> {
adapter.setDeviceList(devices);
adapter.notifyDataSetChanged();
});
});
// 增加设备状态回调的重试机制
private void registerDeviceCallbackWithRetry(int retryCount) {
try {
DeviceManager.registerDeviceStateCallback(callback);
} catch (RemoteException e) {
if (retryCount > 0) {
new Handler().postDelayed(() -> registerDeviceCallbackWithRetry(retryCount - 1), 1000);
}
}
}
未来展望
-
AI设备推荐:智能推荐最适合协同的设备 -
三维空间感知:基于空间位置的自动设备排序 -
跨OS支持:与非鸿蒙设备无缝协同 -
语音控制设备选择:通过语音指令选择设备 -
设备能力可视化:图形化展示设备能力
技术趋势与挑战
趋势
-
泛在协同:任何设备随时加入协同网络 -
意图识别:自动理解用户跨设备操作意图 -
自适应界面:UI根据设备类型自动调整 -
隐私增强:分布式设备管理中的隐私保护 -
能效优化:低功耗设备发现与连接
挑战
-
异构设备兼容:不同芯片平台适配 -
网络环境复杂:弱网环境下的稳定连接 -
安全风险控制:分布式设备的安全防护 -
用户体验一致:多设备交互的统一体验 -
标准化推进:行业统一分布式协议
总结
-
系统架构解析: -
分布式软总线工作原理 -
设备发现与连接机制 -
设备类型标识方法
-
-
关键技术实现: -
设备发现与管理代码 -
按类型过滤设备的方法 -
设备列表的UI展示
-
-
实践方案: -
提供完整可运行的代码示例 -
包含设备列表适配器实现 -
详细的UI布局文件
-
-
创新点: -
设备发现流程图 -
连接建立序列图 -
常见问题解决方案
-
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)