首页 最新 热门 推荐

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

鸿蒙HarmonyOS开发实战—流转(多端协同 二)

  • 25-02-22 03:41
  • 2521
  • 8922
blog.csdn.net
开发步骤

 完成 环境搭建,在DevEco Studio中,选择手机设备,Empty Feature Ability(Java)模板创建项目,在项目自动创建的MainAbility中实现IAbilityContinuation接口。

  1. public class MainAbility extends Ability implements IAbilityContinuation {
  2. private static final int DOMAIN_ID = 0xD001100;
  3. private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, DOMAIN_ID, "MainAbility");
  4. @Override
  5. public void onStart(Intent intent) {
  6. super.onStart(intent);
  7. super.setMainRoute(MainAbilitySlice.class.getName());
  8. }
  9. // 为了方便演示,不在Ability实现流转逻辑,具体逻辑在AbilitySlice中实现
  10. @Override
  11. public boolean onStartContinuation() {
  12. HiLog.info(LABEL_LOG, "onStartContinuation called");
  13. return true;
  14. }
  15. @Override
  16. public boolean onSaveData(IntentParams saveData) {
  17. HiLog.info(LABEL_LOG, "onSaveData called");
  18. return true;
  19. }
  20. @Override
  21. public boolean onRestoreData(IntentParams restoreData) {
  22. HiLog.info(LABEL_LOG, "onRestoreData called");
  23. return true;
  24. }
  25. @Override
  26. public void onCompleteContinuation(int result) {
  27. HiLog.info(LABEL_LOG, "onCompleteContinuation called");
  28. }
  29. }

在AbilitySlice中实现一个用于控制基础功能的页面,以下演示代码逻辑都将在AbilitySlice中实现,代码示例如下:

  1. public class MainAbilitySlice extends AbilitySlice {
  2. private static final int DOMAIN_ID = 0xD000F00;
  3. private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, DOMAIN_ID, "MainAbilitySlice");
  4. @Override
  5. public void onStart(Intent intent) {
  6. super.onStart(intent);
  7. // 开发者可以自行进行界面设计
  8. // 为按钮设置统一的背景色
  9. // 例如通过PositionLayout可以实现简单界面
  10. PositionLayout layout = new PositionLayout(this);
  11. LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
  12. layout.setLayoutConfig(config);
  13. ShapeElement buttonBg = new ShapeElement();
  14. buttonBg.setRgbColor(new RgbColor(0, 125, 255));
  15. super.setUIContent(layout);
  16. }
  17. @Override
  18. public void onInactive() {
  19. super.onInactive();
  20. }
  21. @Override
  22. public void onActive() {
  23. super.onActive();
  24. }
  25. @Override
  26. public void onBackground() {
  27. super.onBackground();
  28. }
  29. @Override
  30. public void onForeground(Intent intent) {
  31. super.onForeground(intent);
  32. }
  33. @Override
  34. public void onStop() {
  35. super.onStop();
  36. }
  37. }

在FA对应的config.json中声明多设备协同访问的权限:ohos.permission.DISTRIBUTED_DATASYNC。在config.json中的配置如下:

  1. {
  2. "module": {
  3. "reqPermissions": [
  4. {
  5. "name": "ohos.permission.DISTRIBUTED_DATASYNC",
  6. "reason": "need",
  7. "usedScene": {
  8. "ability": [
  9. "MainAbility"
  10. ],
  11. "when": "inuse"
  12. }
  13. }
  14. ],
  15. ...
  16. }
  17. ...
  18. }

此外,还需要在FA的onStart()中,调用requestPermissionsFromUser()方法向用户申请权限,代码示例如下:

  1. public class MainAbility extends Ability implements IAbilityContinuation {
  2. @Override
  3. public void onStart(Intent intent) {
  4. super.onStart(intent);
  5. // 开发者显示声明需要使用的权限
  6. requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
  7. ...
  8. }
  9. ...
  10. }

设置流转任务管理服务回调函数,注册流转任务管理服务,管理流转的目标设备,同时需要在流转结束时解注册流转任务管理服务。

  1. public class MainAbilitySlice extends AbilitySlice {
  2. // 当前应用包名
  3. private String BUNDLE_NAME = "XXX.XXX.XXX";
  4. // 流转应用包名
  5. private String REMOTE_BUNDLE_NAME = "XXX.XXX.XXX";
  6. // 流转FA名称
  7. private String REMOTE_FA_NAME = "XXX.XXX.XXX.XXXAbility";
  8. // 流转PA名称
  9. private String REMOTE_PA_NAME = "XXX.XXX.XXX.XXXAbility";
  10. // 注册流转任务管理服务后返回的Ability token
  11. private int abilityToken;
  12. // 用户在设备列表中选择设备后返回的设备ID
  13. private String selectDeviceId;
  14. // 用户是否已发起可拉回流转流程
  15. private boolean isReversibly = false;
  16. // 获取流转任务管理服务管理类
  17. private IContinuationRegisterManager continuationRegisterManager;
  18. // 设置初始化分布式环境的回调
  19. private IInitCallback iInitCallback = new IInitCallback() {
  20. @Override
  21. public void onInitSuccess(String deviceId) {
  22. HiLog.info(LABEL_LOG, "device id success: " + deviceId);
  23. }
  24. @Override
  25. public void onInitFailure(String deviceId, int errorCode) {
  26. HiLog.info(LABEL_LOG, "device id failed: " + deviceId + "errorCode: " + errorCode);
  27. }
  28. };
  29. // 设置流转任务管理服务设备状态变更的回调
  30. private IContinuationDeviceCallback callback = new IContinuationDeviceCallback() {
  31. @Override
  32. public void onConnected(ContinuationDeviceInfo deviceInfo) {
  33. // 在用户选择设备后设置设备ID
  34. selectDeviceId = deviceInfo.getDeviceId();
  35. try {
  36. // 初始化分布式环境
  37. DeviceManager.initDistributedEnvironment(selectDeviceId, iInitCallback);
  38. } catch (RemoteException e) {
  39. HiLog.info(LABEL_LOG, "initDistributedEnvironment failed");
  40. }
  41. //更新选择设备后的流转状态
  42. continuationRegisterManager.updateConnectStatus(abilityToken, selectDeviceId, DeviceConnectState.CONNECTED.getState(), null);
  43. }
  44. @Override
  45. public void onDisconnected(String deviceId) {
  46. }
  47. };
  48. // 设置注册流转任务管理服务回调
  49. private RequestCallback requestCallback = new RequestCallback() {
  50. @Override
  51. public void onResult(int result) {
  52. abilityToken = result;
  53. }
  54. };
  55. ...
  56. @Override
  57. public void onStart(Intent intent) {
  58. ...
  59. continuationRegisterManager = getContinuationRegisterManager();
  60. }
  61. @Override
  62. public void onStop() {
  63. super.onStop();
  64. // 解注册流转任务管理服务
  65. continuationRegisterManager.unregister(abilityToken, null);
  66. // 断开流转任务管理服务连接
  67. continuationRegisterManager.disconnect();
  68. }

为不同功能设置相应的控制按钮。

  1. // 建议开发者按照自己的界面进行按钮设计,示例代码仅供参考
  2. private static final int OFFSET_X = 100;
  3. private static final int OFFSET_Y = 100;
  4. private static final int ADD_OFFSET_Y = 150;
  5. private static final int BUTTON_WIDTH = 800;
  6. private static final int BUTTON_HEIGHT = 100;
  7. private static final int TEXT_SIZE = 50;
  8. private int offsetY = 0;
  9. private Button btnShowDeviceList;
  10. private Button btnStartRemote;
  11. private Button btnStopRemote;
  12. private Button btnConnectRemotePA;
  13. private Button btnControlRemotePA;
  14. private Button btnDisconnectRemotePA;
  15. private Button createButton(String text, ShapeElement buttonBg) {
  16. Button button = new Button(this);
  17. button.setContentPosition(OFFSET_X, OFFSET_Y + offsetY);
  18. offsetY += ADD_OFFSET_Y;
  19. button.setWidth(BUTTON_WIDTH);
  20. button.setHeight(BUTTON_HEIGHT);
  21. button.setTextSize(TEXT_SIZE);
  22. button.setTextColor(Color.YELLOW);
  23. button.setText(text);
  24. button.setBackground(buttonBg);
  25. return button;
  26. }
  27. // 按照顺序在PositionLayout中依次添加按钮的示例
  28. private void addComponents(PositionLayout linear, ShapeElement buttonBg) {
  29. // 构建显示注册流转任务管理服务的按钮
  30. Button btnRegister = createButton("register", buttonBg);
  31. btnRegister.setClickedListener(mRegisterListener);
  32. linear.addComponent(btnRegister);
  33. // 构建显示设备列表的按钮
  34. btnShowDeviceList = createButton("ShowDeviceList", buttonBg);
  35. btnShowDeviceList.setClickedListener(mShowDeviceListListener);
  36. linear.addComponent(btnShowDeviceList);
  37. // 构建远程启动FA/PA的按钮
  38. btnStartRemote = createButton("StartRemote", buttonBg);
  39. btnStartRemote.setClickedListener(mStartRemoteListener);
  40. linear.addComponent(btnStartRemote);
  41. // 构建远程关闭PA的按钮
  42. btnStopRemote = createButton("StopRemote", buttonBg);
  43. btnStopRemote.setClickedListener(mStopRemoteListener);
  44. linear.addComponent(btnStopRemote);
  45. // 构建连接远程PA的按钮
  46. btnConnectRemotePA = createButton("ConnectRemotePA", buttonBg);
  47. btnConnectRemotePA.setClickedListener(mConnectRemotePAListener);
  48. linear.addComponent(btnConnectRemotePA);
  49. // 构建控制连接PA的按钮
  50. btnControlRemotePA = createButton("ControlRemotePA", buttonBg);
  51. btnControlRemotePA.setClickedListener(mControlPAListener);
  52. linear.addComponent(btnControlRemotePA);
  53. // 构建与远程PA断开连接的按钮
  54. btnDisconnectRemotePA = createButton("DisconnectRemotePA", buttonBg);
  55. btnDisconnectRemotePA.setClickedListener(mDisconnectRemotePAListener);
  56. linear.addComponent(btnDisconnectRemotePA);
  57. }
  58. @Override
  59. public void onStart(Intent intent) {
  60. ...
  61. //添加功能按钮布局
  62. addComponents(layout, buttonBg);
  63. super.setUIContent(layout);
  64. }

注册流转任务管理服务。

  1. // 注册流转任务管理服务
  2. private Component.ClickedListener mRegisterListener = new Component.ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. HiLog.info(LABEL_LOG, "register call.");
  6. //增加过滤条件
  7. ExtraParams params = new ExtraParams();
  8. String[] devTypes = new String[]{ExtraParams.DEVICETYPE_SMART_PAD, ExtraParams.DEVICETYPE_SMART_PHONE};
  9. params.setDevType(devTypes);
  10. String jsonParams = "{'filter':{'commonFilter':{'system':{'harmonyVersion':'2.0.0'},'groupType':'1|256','curComType': 0x00030004,'faFilter':'{\"localVersionCode\":1,\"localMinCompatibleVersionCode\":2,\"targetBundleName\": \"com.xxx.yyy\"}'}},'transferScene':0,'remoteAuthenticationDescription': '拉起HiVision扫描弹框描述','remoteAuthenticationPicture':''}";
  11. params.setJsonParams(jsonParams);
  12. continuationRegisterManager.register(BUNDLE_NAME, params, callback, requestCallback);
  13. }
  14. };

通过流转任务管理服务提供的showDeviceList()接口获取选择设备列表,用户选择设备后在IContinuationDeviceCallback回调中获取设备ID。

  1. // 显示设备列表,获取设备信息
  2. private ClickedListener mShowDeviceListListener = new ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. // 设置过滤设备类型
  6. ExtraParams params = new ExtraParams();
  7. String[] devTypes = new String[]{ExtraParams.DEVICETYPE_SMART_PAD, ExtraParams.DEVICETYPE_SMART_PHONE};
  8. params.setDevType(devTypes);
  9. String jsonParams = "{'filter':{'commonFilter':{'system':{'harmonyVersion':'2.0.0'},'groupType':'1|256','curComType': 0x00030004,'faFilter':'{\"localVersionCode\":1,\"localMinCompatibleVersionCode\":2,\"targetBundleName\": \"com.xxx.yyy\"}'}},'transferScene':0,'remoteAuthenticationDescription': '拉起HiVision扫描弹框描述','remoteAuthenticationPicture':''}";
  10. params.setJsonParams(jsonParams);
  11. // 显示选择设备列表
  12. continuationRegisterManager.showDeviceList(abilityToken, params, null);
  13. }
  14. };

为启动远程FA/PA的按钮设置点击回调,实现启动FA/PA和关闭远程PA的能力。

  1. // 启动远程FA/PA
  2. private ClickedListener mStartRemoteListener = new ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. if (selectDeviceId != null) {
  6. // 通过showDeviceList获取指定目标设备deviceId
  7. // 指定待启动FA/PA的bundleName和abilityName
  8. // 设置分布式标记,表明当前涉及分布式能力
  9. Operation operation = new Intent.OperationBuilder()
  10. .withDeviceId(selectDeviceId)
  11. .withBundleName(REMOTE_BUNDLE_NAME)
  12. .withAbilityName(REMOTE_FA_NAME)
  13. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  14. .build();
  15. Intent startIntent = new Intent();
  16. startIntent.setOperation(operation);
  17. // 通过AbilitySlice包含的startAbility接口实现跨设备启动FA/PA
  18. startAbility(startIntent);
  19. } else {
  20. btnStartRemote.setText("StartRemote selectDeviceId is null");
  21. }
  22. }
  23. };
  24. // 关闭远程PA
  25. private ClickedListener mStopRemoteListener = new ClickedListener() {
  26. @Override
  27. public void onClick(Component arg0) {
  28. if (selectDeviceId != null) {
  29. // 通过showDeviceList获取指定目标设备deviceId
  30. // 指定待关闭PA的bundleName和abilityName
  31. // 设置分布式标记,表明当前涉及分布式能力
  32. Operation operation = new Intent.OperationBuilder()
  33. .withDeviceId(selectDeviceId)
  34. .withBundleName(REMOTE_BUNDLE_NAME)
  35. .withAbilityName(REMOTE_PA_NAME)
  36. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  37. .build();
  38. Intent stopIntent = new Intent();
  39. stopIntent.setOperation(operation);
  40. // 通过AbilitySlice包含的stopAbility接口实现跨设备关闭PA
  41. stopAbility(stopIntent);
  42. } else {
  43. btnStopRemote.setText("StopRemote selectDeviceId is null");
  44. }
  45. }
  46. };

需要注意,目标FA/PA需要在config.json中设置“visible”为true。visible标签表示Ability是否可以被其他应用调用,默认为false,即只允许同应用(同appid)访问;如需被其他应用访问,需要将其设置为true,同时建议在目标FA/PA中添加自定义权限,控制访问范围,防止被其他应用随意访问。

在config.json中的配置如下:

  1. {
  2. "module": {
  3. "abilities": [
  4. {
  5. ...
  6. "visible": true
  7. ...
  8. }
  9. ]
  10. ...
  11. }
  12. ...
  13. }

设备A连接设备B侧的PA,利用连接关系调用该PA执行特定任务,以及断开连接。

  1. // 当连接完成时,用来提供管理已连接PA的能力
  2. private MyRemoteProxy mProxy = null;
  3. // 用于管理连接关系
  4. private IAbilityConnection mConn = new IAbilityConnection() {
  5. @Override
  6. public void onAbilityConnectDone(ElementName element, IRemoteObject remote, int resultCode) {
  7. // 跨设备PA连接完成后,会返回一个序列化的IRemoteObject对象
  8. // 通过该对象得到控制远端服务的代理
  9. mProxy = new MyRemoteProxy(remote);
  10. btnConnectRemotePA.setText("connectRemoteAbility done");
  11. }
  12. @Override
  13. public void onAbilityDisconnectDone(ElementName element, int resultCode) {
  14. // 当已连接的远端PA异常关闭时,会触发该回调
  15. // 支持开发者按照返回的错误信息进行PA生命周期管理
  16. disconnectAbility(mConn);
  17. }
  18. };

仅通过启动/关闭两种方式对PA进行调度无法应对需长期交互的场景,因此,系统向开发者提供了跨设备PA连接及断开连接的能力。为了对已连接PA进行管理,开发者需要实现一个满足IAbilityConnection接口的连接状态检测实例,通过该实例可以对连接及断开连接完成时设置具体的处理逻辑,例如:获取控制对端PA的代理等。进一步为了使用该代理跨设备调度PA,开发者需要在本地及对端分别实现对外接口一致的代理。一个具备加法能力的代理示例如下:

  1. // 以连接提供加法计算能力的PA为例。为了提供跨设备连接能力,需要在本地发起连接侧和对端被连接侧分别实现代理
  2. // 发起连接侧的代理示例如下:
  3. public class MyRemoteProxy implements IRemoteBroker {
  4. private static final int ERR_OK = 0;
  5. private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID;
  6. private static final String DESCRIPTOR = "com.XXX.DESCRIPTOR";
  7. private final IRemoteObject remote;
  8. public MyRemoteProxy(IRemoteObject remote) {
  9. this.remote = remote;
  10. }
  11. @Override
  12. public IRemoteObject asObject() {
  13. return remote;
  14. }
  15. public int plus(int a, int b) throws RemoteException {
  16. MessageParcel data = MessageParcel.obtain();
  17. MessageParcel reply = MessageParcel.obtain();
  18. // option不同的取值,决定采用同步或异步方式跨设备控制PA
  19. // 本例需要同步获取对端PA执行加法的结果,因此采用同步的方式,即MessageOption.TF_SYNC
  20. // 具体MessageOption的设置,可参考相关API文档
  21. MessageOption option = new MessageOption(MessageOption.TF_SYNC);
  22. data.writeInterfaceToken(DESCRIPTOR);
  23. data.writeInt(a);
  24. data.writeInt(b);
  25. try {
  26. remote.sendRequest(COMMAND_PLUS, data, reply, option);
  27. int errCode = reply.readInt();
  28. if (errCode != ERR_OK) {
  29. throw new RemoteException();
  30. }
  31. int result = reply.readInt();
  32. return result;
  33. } finally {
  34. data.reclaim();
  35. reply.reclaim();
  36. }
  37. }
  38. }

此外,对端待连接的PA需要实现对应的客户端,代码示例如下所示:

  1. // 以计算加法为例,对端实现的客户端如下
  2. public class MyRemote extends RemoteObject implements IRemoteBroker{
  3. private static final int ERR_OK = 0;
  4. private static final int ERROR = -1;
  5. private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID;
  6. private static final String DESCRIPTOR = "com.XXX.DESCRIPTOR";
  7. public MyRemote() {
  8. super("MyService_Remote");
  9. }
  10. @Override
  11. public IRemoteObject asObject() {
  12. return this;
  13. }
  14. @Override
  15. public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
  16. String token = data.readInterfaceToken();
  17. if (!DESCRIPTOR.equals(token)) {
  18. reply.writeInt(ERROR);
  19. return false;
  20. }
  21. if (code != COMMAND_PLUS) {
  22. reply.writeInt(ERROR);
  23. return false;
  24. }
  25. int value1 = data.readInt();
  26. int value2 = data.readInt();
  27. int sum = value1 + value2;
  28. reply.writeInt(ERR_OK);
  29. reply.writeInt(sum);
  30. return true;
  31. }
  32. }

对端除了要实现如上所述的客户端外,待连接的PA还需要作如下修改:

  1. // 为了返回给连接方可调用的代理,需要在该PA中实例化客户端,例如作为该PA的成员变量
  2. private MyRemote remote = new MyRemote();
  3. // 当该PA接收到连接请求时,即将该客户端转化为代理返回给连接发起侧
  4. @Override
  5. protected IRemoteObject onConnect(Intent intent) {
  6. super.onConnect(intent);
  7. return remote.asObject();
  8. }

创建远程连接目标PA的步骤可参考创建Service。需要注意,目标PA需要在config.json中设置“visible”为true。visible标签表示Ability是否可以被其他应用调用,默认为false,即只允许同应用(同appid)访问;如需被其他应用访问,需要将其设置为true,同时建议在目标PA中添加自定义权限,控制访问范围,防止被其他应用随意访问。

在config.json中的配置如下:

  1. {
  2. "module": {
  3. "abilities": [
  4. {
  5. ...
  6. "visible": true
  7. ...
  8. }
  9. ]
  10. ...
  11. }
  12. ...
  13. }

完成上述步骤后,可以通过点击事件实现连接、利用连接关系控制PA以及断开连接等行为,代码示例如下:

  1. // 连接远程PA
  2. private ClickedListener mConnectRemotePAListener = new ClickedListener() {
  3. @Override
  4. public void onClick(Component arg0) {
  5. if (selectDeviceId != null) {
  6. // 指定待连接PA的bundleName和abilityName
  7. // 设置分布式标记,表明当前涉及分布式能力
  8. Operation operation = new Intent.OperationBuilder()
  9. .withDeviceId(selectDeviceId)
  10. .withBundleName(REMOTE_BUNDLE_NAME)
  11. .withAbilityName(REMOTE_PA_NAME)
  12. .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
  13. .build();
  14. Intent connectPAIntent = new Intent();
  15. connectPAIntent.setOperation(operation);
  16. // 通过AbilitySlice包含的connectAbility接口实现跨设备连接PA
  17. connectAbility(connectPAIntent, mConn);
  18. }
  19. }
  20. };
  21. // 控制已连接PA执行加法
  22. private ClickedListener mControlPAListener = new ClickedListener() {
  23. @Override
  24. public void onClick(Component arg0) {
  25. if (mProxy != null) {
  26. int ret = -1;
  27. try {
  28. ret = mProxy.plus(10, 20);
  29. } catch (RemoteException e) {
  30. HiLog.error(LABEL_LOG, "ControlRemotePA error");
  31. }
  32. btnControlRemotePA.setText("ControlRemotePA result = " + ret);
  33. }
  34. }
  35. };
  36. // 与远程PA断开连接
  37. private ClickedListener mDisconnectRemotePAListener = new ClickedListener() {
  38. @Override
  39. public void onClick(Component arg0) {
  40. // 按钮复位
  41. btnConnectRemotePA.setText("ConnectRemotePA");
  42. btnControlRemotePA.setText("ControlRemotePA");
  43. disconnectAbility(mConn);
  44. }
  45. };

说明 通过连接/断开连接远程PA,与跨设备PA建立长期的管理关系。例如在本例中,通过连接关系得到远程PA的控制代理后,实现跨设备计算加法并将结果返回到本地显示。在实际开发中,开发者可以根据需要实现多种分布式场景,例如:跨设备位置/电量等信息的采集、跨设备计算资源互助等。


最后,为了能让大家更好的去学习提升鸿蒙 (Harmony OS) 开发技术,小编连夜整理了一份30个G纯血版学习资料(含视频、电子书、学习文档等)以及一份在Github上持续爆火霸榜的《纯血版华为鸿蒙 (Harmony OS)开发手册》(共计890页),希望对大家有所帮助。

纯血版鸿蒙 HarmonyOS 4.0 视频学习资料

 需要以上视频学习资料小伙伴

请点击→纯血版全套鸿蒙HarmonyOS学习资料


《纯血版华为鸿蒙 (Harmony OS)开发手册》

这份手册涵盖了当前鸿蒙 (Harmony OS) 开发技术必掌握的核心知识点

纯血版鸿蒙 (Harmony OS)开发手册部分精彩内容

HarmonyOS 概念:

  • 系统定义
  • 技术架构
  • 技术特性
  • 系统安全

如何快速入门?

  • 基本概念
  • 构建第一个ArkTS应用
  • 构建第一个JS应用
  • ……


开发基础知识: 

  • 应用基础知识
  • 配置文件
  • 应用数据管理
  • 应用安全管理
  • 应用隐私保护
  • 三方应用调用管控机制
  • 资源分类与访问
  • 学习ArkTS语言
  • ……

基于ArkTS 开发:

  • Ability开发
  • UI开发
  • 公共事件与通知
  • 窗口管理
  • 媒体
  • 安全
  • 网络与链接
  • 电话服务
  • 数据管理
  • 后台任务(Background Task)管理
  • 设备管理
  • 设备使用信息统计
  • DFX
  • 国际化开发
  • 折叠屏系列
  • .……

获取以上文中提到的这份纯血版鸿蒙 (Harmony OS) 开发资料的小伙伴 

请点击→纯血版全套鸿蒙HarmonyOS学习资料


?写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing?,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新VIP学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

最新鸿蒙Next全套学习资料请扫码
微信名片
注:本文转载自blog.csdn.net的蜀道山QAQ的文章"https://blog.csdn.net/shudaoshanQAQ/article/details/135678312"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

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

分类栏目

后端 (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)

热门文章

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