鸿蒙软总线跨设备访问该怎么玩—小总结

系统
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

重点撸代码:

1、跨设备启动FA、跨设备迁移、回迁

(1)权限

  1. ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE:用于允许监听分布式组网内的设备状态变化。 
  2. ohos.permission.GET_DISTRIBUTED_DEVICE_INFO:用于允许获取分布式组网内的设备列表和设备信息。 
  3. ohos.permission.GET_BUNDLE_INFO:用于查询其他应用的信息。 
  4. ohos.permission.DISTRIBUTED_DATASYNC:用于允许不同设备间的数据交换。 
  5.  
  6. "reqPermissions": [ 
  7.     {"name""ohos.permission.DISTRIBUTED_DATASYNC"}, 
  8.     {"name""ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"},  
  9.     {"name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" },  
  10.    {"name""ohos.permission.GET_BUNDLE_INFO"}  
  11.  
  12. //主动申明,要多设备协同,让用户选择允许还是禁止 
  13. requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0); 

(2)界面:ability_main.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_parent" 
  5.     ohos:width="match_parent" 
  6.     ohos:orientation="vertical"
  7.  
  8.     <Button 
  9.         ohos:id="$+id:main_start_fa_btn" 
  10.         ohos:height="match_content" 
  11.         ohos:width="300vp" 
  12.         ohos:text="1.启动远程设备的FA" 
  13.         ohos:text_size="20fp" 
  14.         ohos:text_color="#ffffff" 
  15.         ohos:background_element="$graphic:button_bg" 
  16.         ohos:layout_alignment="horizontal_center" 
  17.         ohos:top_padding="8vp" 
  18.         ohos:bottom_padding="8vp" 
  19.         ohos:left_padding="40vp" 
  20.         ohos:right_padding="40vp" 
  21.         ohos:top_margin="20vp" 
  22.         /> 
  23.  
  24.     <Button 
  25.         ohos:id="$+id:main_migration_btn" 
  26.         ohos:height="match_content" 
  27.         ohos:width="300vp" 
  28.         ohos:text="2.迁移到远程设备" 
  29.         ohos:text_size="20fp" 
  30.         ohos:text_color="#ffffff" 
  31.         ohos:background_element="$graphic:button_bg" 
  32.         ohos:layout_alignment="horizontal_center" 
  33.         ohos:top_padding="8vp" 
  34.         ohos:bottom_padding="8vp" 
  35.         ohos:left_padding="40vp" 
  36.         ohos:right_padding="40vp" 
  37.         ohos:top_margin="20vp" 
  38.         /> 
  39.      
  40. </DirectionalLayout> 

button_bg.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <shape  xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  3.         ohos:shape="rectangle"
  4.     <solid ohos:color="#007DFF"/> 
  5.     <corners ohos:radius="40"/> 
  6. </shape> 

另外我们需要的Page Abiltiy:MigrationAbility、RemoveAbility

MainAbilitySlice:

  1. public class MainAbilitySlice extends AbilitySlice { 
  2.    private Button mainStartFABtn,mainMigrationBtn; 
  3.  
  4.     @Override 
  5.     public void onStart(Intent intent) { 
  6.         super.onStart(intent); 
  7.         super.setUIContent(ResourceTable.Layout_ability_main); 
  8.         mainStartFABtn = (Button)findComponentById(ResourceTable.Id_main_start_fa_btn); 
  9.         mainMigrationBtn = (Button)findComponentById(ResourceTable.Id_main_migration_btn); 
  10.          
  11.         mainStartFABtn.setClickedListener(mClickListener); 
  12.         mainMigrationBtn.setClickedListener(mClickListener); 
  13.     } 
  14.  
  15.     private Component.ClickedListener mClickListener = new Component.ClickedListener() { 
  16.         @Override 
  17.         public void onClick(Component component) { 
  18.             int compoentId = component.getId(); 
  19.             switch (compoentId){ 
  20.                 case ResourceTable.Id_main_start_fa_btn: 
  21.                     //点击后跨设备打开Fa 
  22.                     //第一种写法 
  23.                     Intent intent = new Intent(); 
  24.                     Operation op = new Intent.OperationBuilder() 
  25.                             .withDeviceId(Common.getOnLineDeviceId()) 
  26.                             .withBundleName("com.ybzy.demo"
  27.                             .withAbilityName("com.ybzy.demo.RemoveAbility"
  28.                             .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) 
  29.                             .build(); 
  30.                     intent.setOperation(op); 
  31.                     intent.setParam("msg","我夸设备把你这个FA拉起来了!"); 
  32.                     startAbility(intent); 
  33.  
  34.                     //第二钟写法 
  35.                     intent.setElement(new ElementName(Common.getOnLineDeviceId() 
  36.                                             ,"com.ybzy.demo","com.ybzy.demo.RemoveAbility")); 
  37.                     intent.setFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE); 
  38.                     intent.setParam("msg","我夸设备把你这个FA拉起来了!"); 
  39.                     startAbility(intent); 
  40.  
  41.                     break; 
  42.                 case ResourceTable.Id_main_migration_btn: 
  43.                     //点击后进入要迁移的Ability页面 
  44.                     Intent migrationIntent = new Intent(); 
  45.                     migrationIntent.setElement(new ElementName("","com.ybzy.demo" 
  46.                                                     ,"com.ybzy.demo.MigrationAbility")); 
  47.                     startAbility(migrationIntent); 
  48.                     break; 
  49.                 default
  50.                     break; 
  51.             } 
  52.         } 
  53.     }; 
  54.  
  55.     @Override 
  56.     public void onActive() { 
  57.         super.onActive(); 
  58.     } 
  59.  
  60.     @Override 
  61.     public void onForeground(Intent intent) { 
  62.         super.onForeground(intent); 
  63.     } 

ability_migration.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_parent" 
  5.     ohos:width="match_parent" 
  6.     ohos:background_element="#00ffff" 
  7.     ohos:orientation="vertical"
  8.  
  9.     <Text 
  10.         ohos:id="$+id:migration_text" 
  11.         ohos:height="match_content" 
  12.         ohos:width="250vp" 
  13.         ohos:background_element="#0088bb" 
  14.         ohos:layout_alignment="horizontal_center" 
  15.         ohos:text="下面是一个可编辑的文本框" 
  16.         ohos:text_size="50" 
  17.         ohos:padding="5vp" 
  18.         ohos:top_margin="30vp" 
  19.         /> 
  20.  
  21.     <TextField 
  22.         ohos:id="$+id:migration_textfield" 
  23.         ohos:height="250vp" 
  24.         ohos:width="250vp" 
  25.         ohos:hint="请输入..." 
  26.         ohos:layout_alignment="horizontal_center" 
  27.         ohos:background_element="#ffffff" 
  28.         ohos:text_color="#888888" 
  29.         ohos:text_size="20fp" 
  30.         ohos:padding="5vp" 
  31.         /> 
  32.     <Button 
  33.         ohos:id="$+id:migration_migration_btn" 
  34.         ohos:height="match_content" 
  35.         ohos:width="match_content" 
  36.         ohos:text="点击迁移" 
  37.         ohos:text_size="20fp" 
  38.         ohos:text_color="#ffffff" 
  39.         ohos:background_element="$graphic:button_bg" 
  40.         ohos:top_padding="8vp" 
  41.         ohos:bottom_padding="8vp" 
  42.         ohos:left_padding="50vp" 
  43.         ohos:right_padding="50vp" 
  44.         ohos:layout_alignment="horizontal_center" 
  45.         ohos:top_margin="30vp" 
  46.         /> 
  47.  
  48.     <Button 
  49.         ohos:id="$+id:migration_migration_back_btn" 
  50.         ohos:height="match_content" 
  51.         ohos:width="match_content" 
  52.         ohos:text="点击迁移回来" 
  53.         ohos:text_size="20fp" 
  54.         ohos:text_color="#ffffff" 
  55.         ohos:background_element="$graphic:button_bg" 
  56.         ohos:top_padding="8vp" 
  57.         ohos:bottom_padding="8vp" 
  58.         ohos:left_padding="50vp" 
  59.         ohos:right_padding="50vp" 
  60.         ohos:layout_alignment="horizontal_center" 
  61.         ohos:top_margin="30vp" 
  62.         /> 
  63. </DirectionalLayout> 

RemoveAbility...把接收到的值显示到页面就行,setText()

(3)工具类

  1. public class Common{ 
  2.     public static String getDeviceId(){ 
  3.         List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  4.         if(deviceList.isEmpty()){ 
  5.             return null
  6.         } 
  7.         int deviceNum = deviceList.size(); 
  8.         List<String> deviceIds = new ArrayList<>(deviceNum); 
  9.         List<String> deviceNames = new ArrayList<>(deviceNum); 
  10.         deviceList.forEach((device)->{ 
  11.             deviceIds.add(device.getDeviceId()); 
  12.             deviceNames.add(device.getDeviceName()); 
  13.         }); 
  14.  
  15.         //我们这里的实验环境,就两部手机,组件还没讲 
  16.         //我就直接使用deviceIds的第一个元素,做为启动远程设备的目标id 
  17.         String devcieIdStr = deviceIds.get(0); 
  18.         return devcieIdStr; 
  19.     } 
  20.  
  21.  
  22.     public static void myShowTip(Context context,String msg){ 
  23.         //提示框的核心组件文本 
  24.         Text text = new Text(context); 
  25.         text.setWidth(MATCH_CONTENT); 
  26.         text.setHeight(MATCH_CONTENT); 
  27.         text.setTextSize(16, Text.TextSizeType.FP); 
  28.         text.setText(msg); 
  29.         text.setPadding(30,20,30,20); 
  30.         text.setMultipleLine(true); 
  31.         text.setMarginLeft(30); 
  32.         text.setMarginRight(30); 
  33.         text.setTextColor(Color.WHITE); 
  34.         text.setTextAlignment(TextAlignment.CENTER); 
  35.      
  36.         //给上面的文本设置一个背景样式 
  37.         ShapeElement style = new ShapeElement(); 
  38.         style.setShape(ShapeElement.RECTANGLE); 
  39.         style.setRgbColor(new RgbColor(77,77,77)); 
  40.         style.setCornerRadius(15); 
  41.         text.setBackground(style); 
  42.      
  43.         //构建存放上面的text的布局 
  44.         DirectionalLayout mainLayout = new DirectionalLayout(context); 
  45.         mainLayout.setWidth(MATCH_PARENT); 
  46.         mainLayout.setHeight(MATCH_CONTENT); 
  47.         mainLayout.setAlignment(LayoutAlignment.CENTER); 
  48.         mainLayout.addComponent(text); 
  49.      
  50.         //最后要让上面的组件绑定dialog 
  51.         ToastDialog toastDialog = new ToastDialog(context); 
  52.         toastDialog.setSize(MATCH_PARENT,MATCH_CONTENT); 
  53.         toastDialog.setDuration(1500); 
  54.         toastDialog.setAutoClosable(true); 
  55.         toastDialog.setTransparent(true); 
  56.         toastDialog.setAlignment(LayoutAlignment.CENTER); 
  57.         toastDialog.setComponent((Component) mainLayout); 
  58.         toastDialog.show(); 
  59.     } 
  60.      

(4)实现功能

MigrationAbilitySlice:

  1. public class MigrationAbilitySlice extends AbilitySlice implements IAbilityContinuation { 
  2.     TextField migrationTextField; 
  3.     Button migrationMigrationBtn,migrationMigrationBackBtn; 
  4.     String msg = ""
  5.  
  6.     @Override 
  7.     public void onStart(Intent intent) { 
  8.         super.onStart(intent); 
  9.         super.setUIContent(ResourceTable.Layout_ability_migration); 
  10.  
  11.         migrationTextField = (TextField)findComponentById(ResourceTable.Id_migration_textfield); 
  12.         migrationTextField.setText(msg); 
  13.         migrationMigrationBtn = (Button)findComponentById(ResourceTable.Id_migration_migration_btn); 
  14.         migrationMigrationBtn.setClickedListener(component -> { 
  15.             //1、要进行迁移的Ability实现接口 IAbilityContinuation,实现的方法返回值改成true 
  16.             //2、要进行迁移的Ability下面关联的所有AbilitySlice都要实现接口 IAbilityContinuation, 
  17.             //  实现的方法上处理数据 
  18.             //3、进行迁移 
  19.             String deviceId = Common.getOnLineDeviceId(); 
  20.             if(deviceId != null){ 
  21. //                continueAbility(deviceId);  
  22.                 continueAbilityReversibly(deviceId); 
  23.             } 
  24.         }); 
  25.  
  26.         migrationMigrationBackBtn = (Button) findComponentById(ResourceTable 
  27.                                                                     .Id_migration_migration_back_btn); 
  28.         migrationMigrationBackBtn.setClickedListener(component -> { 
  29.             reverseContinueAbility(); 
  30.         }); 
  31.     } 
  32.  
  33.     @Override 
  34.     public void onActive() { 
  35.         super.onActive(); 
  36.     } 
  37.  
  38.     @Override 
  39.     public void onForeground(Intent intent) { 
  40.         super.onForeground(intent); 
  41.     } 
  42.  
  43.     @Override 
  44.     public boolean onStartContinuation() { 
  45.         return true
  46.     } 
  47.  
  48.     @Override 
  49.     public boolean onSaveData(IntentParams intentParams) { 
  50.         intentParams.setParam("msg",migrationTextField.getText()); 
  51.         return true
  52.     } 
  53.  
  54.     @Override 
  55.     public boolean onRestoreData(IntentParams intentParams) { 
  56.         msg = intentParams.getParam("msg").toString(); 
  57. //        getUITaskDispatcher().asyncDispatch(() -> { 
  58. //            migrationTextField.setText(intentParams.getParam("msg").toString()); 
  59. //        }); 
  60.         return true
  61.     } 
  62.  
  63.     @Override 
  64.     public void onCompleteContinuation(int i) { 
  65.  
  66.     } 
  67.  

2、跨设备连接Service

启动远程设备Service的代码示例如下:

添加按钮:

  1. <Button 
  2.     ohos:id="$+id:main_start_removeService_btn" 
  3.     ohos:height="match_content" 
  4.     ohos:width="300vp" 
  5.     ohos:text="远程启动ServiceAbility" 
  6.     ohos:text_size="20fp" 
  7.     ohos:text_color="#ffffff" 
  8.     ohos:background_element="$graphic:button_bg" 
  9.     ohos:layout_alignment="horizontal_center" 
  10.     ohos:top_padding="8vp" 
  11.     ohos:bottom_padding="8vp" 
  12.     ohos:left_padding="40vp" 
  13.     ohos:right_padding="40vp" 
  14.     ohos:top_margin="20vp" 
  15.     /> 
  16.      
  17.     <Button 
  18.     ohos:id="$+id:main_stop_removeService_btn" 
  19.     ohos:height="match_content" 
  20.     ohos:width="300vp" 
  21.     ohos:text="远程关闭ServiceAbility" 
  22.     ohos:text_size="20fp" 
  23.     ohos:text_color="#ffffff" 
  24.     ohos:background_element="$graphic:button_bg" 
  25.     ohos:layout_alignment="horizontal_center" 
  26.     ohos:top_padding="8vp" 
  27.     ohos:bottom_padding="8vp" 
  28.     ohos:left_padding="40vp" 
  29.     ohos:right_padding="40vp" 
  30.     ohos:top_margin="20vp" 
  31.     /> 

新建RemoteServiceAbility:

  1. public class RemoteServiceAbility extends Ability { 
  2.     private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo"); 
  3.     private Source sVideoSource; 
  4.     private Player sPlayer; 
  5.  
  6.     @Override 
  7.     public void onStart(Intent intent) { 
  8.         HiLog.error(LABEL_LOG, "RmoteServiceAbility::onStart"); 
  9.         super.onStart(intent); 
  10.         Common.myShowTip(this,"remote onstart"); 
  11.         sPlayer = new Player(RemoteServiceAbility.this); 
  12.         new PlayerThread().start(); 
  13.     } 
  14.     class PlayerThread extends Thread { 
  15.         @Override 
  16.         public void run() { 
  17.             try { 
  18.                 File mp3FilePath = getExternalFilesDir(Environment.DIRECTORY_MUSIC); 
  19.                 if (!mp3FilePath.exists()) { 
  20.                     mp3FilePath.mkdirs(); 
  21.                 } 
  22.                 File mp3File = new File(mp3FilePath.getAbsolutePath() + "/" + "bj.mp3"); 
  23.  
  24.                 Resource res = getResourceManager() 
  25.                         .getRawFileEntry("resources/rawfile/bj.mp3").openRawFile(); 
  26.                 byte[] buf = new byte[4096]; 
  27.                 int count = 0; 
  28.                 FileOutputStream fos = new FileOutputStream(mp3File); 
  29.                 while ((count = res.read(buf)) != -1) { 
  30.                     fos.write(buf, 0, count); 
  31.                 } 
  32.                 FileDescriptor fileDescriptor = new FileInputStream(mp3File).getFD(); 
  33.                 sVideoSource = new Source(fileDescriptor); 
  34.                 sPlayer.setSource(sVideoSource); 
  35.                 sPlayer.prepare(); 
  36.                 sPlayer.setVolume(0.3f); 
  37.                 sPlayer.enableSingleLooping(true); 
  38.                 sPlayer.play(); 
  39.             } catch (IOException e) { 
  40.                 e.printStackTrace(); 
  41.             } 
  42.         } 
  43.     } 
  44.  
  45.     @Override 
  46.     public void onStop() { 
  47.         super.onStop(); 
  48.         Common.myShowTip(RemoteServiceAbility.this,"remote onStop"); 
  49.         sPlayer.stop(); 
  50.     } 
  51.  
  52.     @Override 
  53.     public IRemoteObject onConnect(Intent intent) { 
  54.         return null
  55.     } 
  56.     @Override 
  57.     public void onDisconnect(Intent intent) { 
  58.     } 

启动:

  1. case ResourceTable.Id_main_start_remoteService_btn: 
  2.  
  3.     Common.myShowTip(MainAbilitySlice.this,deviceId); 
  4.     Intent startRemoteServiceIntent = new Intent(); 
  5.     startRemoteServiceIntent.setElement(new ElementName( 
  6.             deviceId, 
  7.             "com.ybzy.demo"
  8.             "com.ybzy.demo.RemoteServiceAbility" 
  9.     )); 
  10.     startRemoteServiceIntent.setFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE); 
  11.     startAbility(startRemoteServiceIntent); 
  12.     break; 

关闭远程设备Service:

  1. case ResourceTable.Id_main_stop_remoteService_btn: 
  2.     Common.myShowTip(MainAbilitySlice.this,deviceId); 
  3.     Intent stopRemoteServiceIntent = new Intent(); 
  4.     stopRemoteServiceIntent.setElement(new ElementName( 
  5.             deviceId, 
  6.             "com.ybzy.demo"
  7.             "com.ybzy.demo.RemoteServiceAbility" 
  8.     )); 
  9.     stopRemoteServiceIntent.setFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE); 
  10.     stopAbility(stopRemoteServiceIntent); 
  11.     break; 

仅通过启动和停止Service Ability两种方式对Service进行调度无法应对需长期交互的场景,

简单地说,信息就是只能去,回不来!

因此,分布式任务调度平台向开发者提供了跨设备Service连接及断开连接的能力。

链接上了,信息可去可回!

链接是使用connectAbility()方法,需要传入目标Service的Intent与接口IAbilityConnection的实例对象。

接口IAbilityConnection提供了两个方法供开发者实现:

(1)onAbilityConnectDone()用来处理连接的回调。

(2)onAbilityDisconnectDone()用来处理断开连接的回调。

我们可以在onAbilityConnectDone()中获取管理链接的代理,进一步为了使用该代理跨设备调度Service,

开发者需要在本地及远端分别实现对外接口一致的代理,这个接口是IRemoteBroker。

添加按钮:

  1. <Button 
  2.     ohos:id="$+id:main_connect_remoteService_btn" 
  3.     ohos:height="match_content" 
  4.     ohos:width="300vp" 
  5.     ohos:text="远程链接ServiceAbility" 
  6.     ohos:text_size="20fp" 
  7.     ohos:text_color="#ffffff" 
  8.     ohos:background_element="$graphic:button_bg" 
  9.     ohos:layout_alignment="horizontal_center" 
  10.     ohos:top_padding="8vp" 
  11.     ohos:bottom_padding="8vp" 
  12.     ohos:left_padding="40vp" 
  13.     ohos:right_padding="40vp" 
  14.     ohos:top_margin="20vp" 
  15.     /> 
  16.  
  17. <Button 
  18.     ohos:id="$+id:main_use_remoteService_btn" 
  19.     ohos:height="match_content" 
  20.     ohos:width="300vp" 
  21.     ohos:text="使用远程ServiceAbility" 
  22.     ohos:text_size="20fp" 
  23.     ohos:text_color="#ffffff" 
  24.     ohos:background_element="$graphic:button_bg" 
  25.     ohos:layout_alignment="horizontal_center" 
  26.     ohos:top_padding="8vp" 
  27.     ohos:bottom_padding="8vp" 
  28.     ohos:left_padding="40vp" 
  29.     ohos:right_padding="40vp" 
  30.     ohos:top_margin="20vp" 
  31.     /> 
  32.  
  33. <Button 
  34.     ohos:id="$+id:main_disconnect_remoteService_btn" 
  35.     ohos:height="match_content" 
  36.     ohos:width="300vp" 
  37.     ohos:text="远程断开ServiceAbility" 
  38.     ohos:text_size="20fp" 
  39.     ohos:text_color="#ffffff" 
  40.     ohos:background_element="$graphic:button_bg" 
  41.     ohos:layout_alignment="horizontal_center" 
  42.     ohos:top_padding="8vp" 
  43.     ohos:bottom_padding="8vp" 
  44.     ohos:left_padding="40vp" 
  45.     ohos:right_padding="40vp" 
  46.     ohos:top_margin="20vp" 
  47.     /> 

发起连接的本地侧的代理示例如下:

  1. public class MyRemoteProxy implements IRemoteBroker { 
  2.     //IRemoteBroker:获取远程代理对象的持有者 
  3.     private static final int ERR_OK = 0; 
  4.     //COMMAND_PLUS表示有效消息进行通信的约定的标记,MIN_TRANSACTION_ID是这个标记可以用的最小值:1 
  5.     private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID; 
  6.  
  7.     //IRemoteObject:此接口 
  8.     // 可用于查询或获取接口描述符、 
  9.     // 添加或删除死亡通知、 
  10.     // 将对象状态转储到特定文件以及发送消息。 
  11.     private final IRemoteObject remote; 
  12.     public MyRemoteProxy(IRemoteObject remote) { 
  13.         this.remote = remote; 
  14.     } 
  15.  
  16.     @Override 
  17.     public IRemoteObject asObject() {//获取远程代理对象的方法 
  18.         return remote; 
  19.     } 
  20.  
  21.     public int plus(int a,int b) throws RemoteException { 
  22.         //MessageParcel:这个类提供了读写对象、接口标记、文件描述符和大数据的方法。 
  23.         MessageParcel data = MessageParcel.obtain(); 
  24.         //obtain()创建索引为0的空MessageParcel对象 
  25.         MessageParcel reply = MessageParcel.obtain(); 
  26.  
  27.         //MessageOption:定义与sendRequest一起发送消息的选项。 
  28.         // option不同的取值,决定采用同步或异步方式跨设备调用Service 
  29.         // 这个例子我们需要同步获取对端Service执行加法运算后的结果,同步模式调用sendRequest接口,即MessageOption.TF_SYNC 
  30.         // 对应的是异步:TF_ASYNC 
  31.         MessageOption option = new MessageOption(MessageOption.TF_SYNC); 
  32.         data.writeInt(a); 
  33.         data.writeInt(b); 
  34.  
  35.         try { 
  36.             remote.sendRequest(COMMAND_PLUS, data, reply, option); 
  37.             //第1个参数:约定通信双方确定的消息标记。 
  38.             //第2个参数:发送到对等端侧的数据包裹MessageParcel对象。 
  39.             //第3个参数:对等端侧返回的数据包裹MessageParcel对象。 
  40.             //第4个参数:设置发送消息,用同步还是异步模式。 
  41.             int ec = reply.readInt(); //返回通信成不成功,约定的标记ERR_OK 
  42.             if (ec != ERR_OK) { 
  43.                 throw new RemoteException(); 
  44.             } 
  45.             int result = reply.readInt(); 
  46.             return result; 
  47.         } catch (RemoteException e) { 
  48.             throw new RemoteException(); 
  49.         } finally { 
  50.             data.reclaim(); //reclaim()清除不再使用的MessageParcel对象。 
  51.             reply.reclaim(); 
  52.         } 
  53.     } 

等待连接的远端侧的代理示例如下:

  1. public class MyRemote extends RemoteObject implements IRemoteBroker{ 
  2.     private static final int ERR_OK = 0; 
  3.     private static final int ERROR = -1; 
  4.     private static final int COMMAND_PLUS = IRemoteObject.MIN_TRANSACTION_ID; 
  5.   
  6.     public MyRemote() { 
  7.         super("MyService_Remote"); 
  8.     } 
  9.   
  10.     @Override 
  11.     public IRemoteObject asObject() { 
  12.         return this; 
  13.     } 
  14.   
  15.     @Override 
  16.     public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) { 
  17.         if (code != COMMAND_PLUS) { 
  18.             reply.writeInt(ERROR); 
  19.             return false
  20.         } 
  21.         int value1 = data.readInt(); 
  22.         int value2 = data.readInt(); 
  23.         int sum = value1 + value2; 
  24.         reply.writeInt(ERR_OK); 
  25.         reply.writeInt(sum); 
  26.         return true
  27.     } 

等待连接侧还需要作如下修改:

  1. // 绑定前面定义的代理,实例化出发起链接侧需要的代理 
  2. private MyRemote remote = new MyRemote(); 
  3. @Override 
  4. public IRemoteObject onConnect(Intent intent) { 
  5.     //链接成功的时候,给发起链接侧返回去 
  6.     return remote.asObject(); 

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

  1. private MyRemoteProxy mProxy = null
  2. // 创建连接回调实例 
  3. private IAbilityConnection conn = new IAbilityConnection() { 
  4.     // 连接到Service的回调 
  5.     @Override 
  6.     public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) { 
  7.         // 在这里开发者可以拿到服务端传过来IRemoteObject对象,从中解析出服务端传过来的信息 
  8.         mProxy = new MyRemoteProxy(iRemoteObject); 
  9.         UIUtils.showTip(MainAbilitySlice.this,"拿到remoteObject:" + mProxy); 
  10.     } 
  11.  
  12.     // 意外断开连接才会回调 
  13.     @Override 
  14.     public void onAbilityDisconnectDone(ElementName elementName, int resultCode) { 
  15.     } 
  16. }; 
  17.  
  18.  
  19.  
  20. // 连接远程 
  21. case ResourceTable.Id_main_connect_remoteService_btn: 
  22.     //1、实现连接的本地侧的代理 
  23.     //2、实现等待连接的远端侧的代理 
  24.     //3、修改等待连接侧的Service 
  25.     //4、在本地(发起链接侧)获取远端(被链接侧)返回过来的链接代理,创建链接后的回调函数 
  26.     //5、实现链接,通过代理对象使用Service的服务 
  27.     if (deviceId != null) { 
  28.         Intent connectServiceIntent = new Intent(); 
  29.         connectServiceIntent.setElement(new ElementName( 
  30.                 deviceId, 
  31.                 "com.ybzy.demo"
  32.                 "com.ybzy.demo.RemoteServiceAbility" 
  33.         )); 
  34.         connectServiceIntent.setFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE); 
  35.         connectAbility(connectServiceIntent, iAbilityConnection); 
  36.     } 
  37.     break; 
  38.      
  39.      
  40. // 链接后使用 
  41. case ResourceTable.Id_main_use_remoteService_btn: 
  42.     if (mProxy != null) { 
  43.         int ret = -1; 
  44.         try { 
  45.             ret = mProxy.plus(10, 20); 
  46.         } catch (RemoteException e) { 
  47.             e.printStackTrace(); 
  48.         } 
  49.         Common.myShowTip(MainAbilitySlice.this, "获取的结果:" + ret); 
  50.     } 
  51.     break; 
  52.      
  53. // 用完断开 
  54. case ResourceTable.Id_main_disconnect_remoteService_btn: 
  55.     disconnectAbility(iAbilityConnection); 
  56.     break; 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-01-06 10:59:14

鸿蒙HarmonyOSPage Abilit

2021-08-20 14:27:50

鸿蒙HarmonyOS应用

2011-07-18 09:12:49

远程访问VPNSSL VPNIPSec VPN

2012-06-26 11:27:40

Windows Pho

2020-11-05 10:05:25

App

2021-01-06 11:21:56

鸿蒙HarmonyOS应用开发

2015-09-06 09:56:26

大数据企业存储

2020-11-16 11:29:40

HarmonyOS

2021-10-28 14:48:46

鸿蒙HarmonyOS应用

2014-08-28 10:48:14

筋斗云

2017-11-16 14:46:58

Linuxplatform总线驱动设备

2010-06-08 16:55:46

CANopen总线协议

2010-06-08 15:55:14

CAN总线协议

2011-04-15 10:22:32

路由器软路由网段

2022-07-01 16:55:17

调试板子手势操作

2016-05-25 10:34:38

运维月活千万

2014-12-24 13:51:33

用友优普

2021-01-20 05:35:08

PythonMock微服务

2022-11-28 15:42:39

分布式软总线鸿蒙

2018-06-07 22:10:42

阿里云ET农业大脑
点赞
收藏

51CTO技术栈公众号