上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

OpenHarmony与HarmonyOS实现信息交流(一)

guduadmin341月前

在过去很长一段时间,我都非常希望能够将OpenHarmony与HarmonyOS设备进行一个联动,但是碍于一些底层接口未完善一直无法实现。但是在前几个月,OpenHarmony3.1 带来了更多可能。本次,我将分享如何在搭载HarmonyOS的手机和搭载OpenHarmony的开发板上,实现socket对话!

0. 效果演示

OpenHarmony与HarmonyOS实现信息交流(一),3b58690cc4f7008af51012d0b83be9592022614200511.gif,第1张

1.HarmonyOS侧

1.1 新建一个JAVA工程,编写简单的测试页面

OpenHarmony与HarmonyOS实现信息交流(一),2400cd386d14f24cc91430a61e150715bb83e1.png,第2张

  • ability_main.xml (主页面)
    
    
        
        

    这是我自己编写的一个测试页面,但不是最重要的。

    1.2 编写socket功能

    目前,鸿蒙的Socket通信功能只能在JAVA侧实现,并且官网对相关的功能解析不够全面,但是足够实现UDP通信。

    这里直接参考官网,可以快速实现Socket功能,传送门:​​JAVA-socket

    在MainAbilitySlice中编写两个主要函数,并结合个人情况绑定到测试按键上即可。

    • StartServer()
      HiLog.info(LABEL_LOG, "StartServer run");
                      NetManager netManager = NetManager.getInstance(null);
                      if (!netManager.hasDefaultNet()) {
                          HiLog.error(LABEL_LOG,
                                  "netManager.hasDefaultNet() failed");
                          return;
                      }
                      NetHandle netHandle = netManager.getDefaultNet();
                      DatagramSocket socket = null;
                      // 通过Socket绑定来进行数据传输
                      try {
                          HiLog.info(LABEL_LOG, "wait receive data");
                          //通过getLocalIpAddress()快速获取本机的IP地址
                          InetAddress address = netHandle.getByName(getLocalIpAddress());
                          //端口号+主机地址
                          socket = new DatagramSocket(10006, address);
                          netHandle.bindSocket(socket);
                          /*至此绑定Socket结束*/
                          HiLog.info(LABEL_LOG, "绑定成功");
                          /*监听函数*/
                          byte[] buffer = new byte[1024];
                          DatagramPacket response = new DatagramPacket(buffer,
                                  buffer.length);
                          while (true) {
                              //接收数据
                              socket.receive(response);
                              int len = response.getLength();
                              HiLog.info(LABEL_LOG, "接收成功");
                              //将数据打印到屏幕上
                              s = new String(buffer, StandardCharsets.UTF_8).substring(0,
                                      len);
                                      //一个textfield组件
                                      text.setText(s);
                             
                              HiLog.info(LABEL_LOG, "receive data: " + s);
                          }
                      } catch (IOException e) {
                          HiLog.error(LABEL_LOG, "rev IOException: ");
                      }
                  }
      
      • sendMessage()
        NetManager netManager = NetManager.getInstance(null);
                        if (!netManager.hasDefaultNet()) {
                            HiLog.error(LABEL_LOG,
                                    "netManager.hasDefaultNet() failed");
                            return;
                        }
                        NetHandle netHandle = netManager.getDefaultNet();
                        // 通过Socket绑定来进行数据传输
                        DatagramSocket socket = null;
                        try {
                            //从textfield组件获取用户输入的对端ip地址
                            HOST = iptf.getText();
                            InetAddress address = netHandle.getByName(HOST);
                            socket = new DatagramSocket();
                            netHandle.bindSocket(socket);
                            /*至此 已绑定对端Socket*/
                            //从一个textfield组件获取用户输入的要发送的信息。
                            String data = new String(sendtf.getText());
                            //这里默认还是发送至对端的10006端口
                            DatagramPacket request = new DatagramPacket(data.getBytes(
                                    StandardCharsets.UTF_8), data.length(),
                                    address, PORT);
                            // buffer赋值
                            // 发送数据
                            socket.send(request);
                            HiLog.info(LABEL_LOG, "send data: " + data);
                        } catch (IOException e) {
                            HiLog.error(LABEL_LOG, "send IOException: ");
                        } finally {
                            if (null != socket) {
                            }
                        }
        
        • getlocalip()
          private String getLocalIpAddress() {
                  WifiDevice wifiDevice = WifiDevice.getInstance(getContext());
                  Optional ipInfo = wifiDevice.getIpInfo();
                  int ip = ipInfo.get().getIpAddress();
                  return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + (ip >> 24 & 0xFF);
              }
          

          至此,接收信息和发送信息的函数都编写完了。但并没有结束,这样的函数并不能跑在UI线程上,我们必须让其在其他线程上运作,那必须请出我们最爱的EventRunner.

          1.3 编写Mythread类

          EventRunner传送门

          package com.example.hoop.util;
          import ohos.eventhandler.EventHandler;
          import ohos.eventhandler.EventRunner;
          public class Mythread {
              public static void inUI(Runnable runnable) {
                  //返回主线程
                  EventRunner runner = EventRunner.getMainEventRunner();
                  EventHandler eventHandler = new EventHandler(runner);
                  eventHandler.postSyncTask(runnable);
              }
              public static void inBG(Runnable runnable) {
                  EventRunner runner = EventRunner.create(true);
                  EventHandler eventHandler = new EventHandler(runner);
                  //投递任务,我们的Socket函数应该投递于此。
                  eventHandler.postTask(runnable, 0, EventHandler.Priority.IMMEDIATE);
              }
          }
          
          • 将任务投递给EventRunner

            只需要将刚刚的两个主要函数投递就行了

            private void sendMessage() {
                    Mythread.inBG(new Runnable() {
                        @Override
                        public void run() {
                            NetManager netManager = NetManager.getInstance(null);
                            if (!netManager.hasDefaultNet()) {
                                HiLog.error(LABEL_LOG,"netManager.hasDefaultNet() failed");
                                return;
                            }
                            NetHandle netHandle = netManager.getDefaultNet();
                            // 通过Socket绑定来进行数据传输
                            DatagramSocket socket = null;
                            try {
                                //从textfield组件获取用户输入的对端ip地址
                                HOST=iptf.getText();
                                InetAddress address = netHandle.getByName(HOST);
                                socket = new DatagramSocket();
                                netHandle.bindSocket(socket);
                                /*至此 已绑定对端Socket*/
                                //从一个textfield组件获取用户输入的要发送的信息。
                                String data = new String(sendtf.getText());
                                //这里默认还是发送至对端的10006端口
                                DatagramPacket request = new DatagramPacket(data.getBytes(StandardCharsets.UTF_8), data.length(), address, PORT);
                                // buffer赋值
                                // 发送数据
                                socket.send(request);
                                HiLog.info(LABEL_LOG,"send data: " + data);
                            } catch (IOException e) {
                                HiLog.error(LABEL_LOG,"send IOException: ");
                            } finally {
                                if (null != socket) {
                                }
                            }
                        }
                    });
                }
                private void StartServer() {
                    Mythread.inBG(new Runnable() {
                        @Override
                        public void run() {
                            HiLog.info(LABEL_LOG,"StartServer run");
                            NetManager netManager = NetManager.getInstance(null);
                            if (!netManager.hasDefaultNet()) {
                                HiLog.error(LABEL_LOG,"netManager.hasDefaultNet() failed");
                                return;
                            }
                            NetHandle netHandle = netManager.getDefaultNet();
                            DatagramSocket socket = null;
                            // 通过Socket绑定来进行数据传输
                            try {
                                HiLog.info(LABEL_LOG,"wait receive data");
                                //通过getLocalIpAddress()快速获取本机的IP地址
                                InetAddress address = netHandle.getByName(getLocalIpAddress());
                                //端口号+主机地址
                                socket = new DatagramSocket(10006, address);
                                netHandle.bindSocket(socket);
                                /*至此绑定Socket结束*/
                                HiLog.info(LABEL_LOG,"绑定成功");
                                /*监听函数*/
                                byte[] buffer = new byte[1024];
                                DatagramPacket response = new DatagramPacket(buffer, buffer.length);
                                while(true){
                                    //接收数据
                                    socket.receive(response);
                                    int len = response.getLength();
                                    HiLog.info(LABEL_LOG,"接收成功");
                                    //将数据打印到屏幕上
                                    s = new String(buffer, StandardCharsets.UTF_8).substring(0, len);
                                    Mythread.inUI(new Runnable() {
                                        @Override
                                        public void run() {
                                            //一个textfield组件
                                            text.setText(s);
                                        }
                                    });
                                    HiLog.info(LABEL_LOG,"receive data: " + s);
                                }
                            } catch (IOException e) {
                                HiLog.error(LABEL_LOG,"rev IOException: " );
                            }
                        }
                    });
                }
            

            2.OpenHarmony侧

            2.1 新建工程,编写测试页面

            OpenHarmony与HarmonyOS实现信息交流(一),c84ec8089e8ea99bdba912eeb199c1a5f9b432.png,第3张

            • index.hml
              {{ title }} 本机IP{{getIpAddress()}}

              2.2 编写Socket功能

              OpenHarmony-Socket

              import socket from '@ohos.net.socket';
              import wifi from '@ohos.wifi';
              export default {
                  data: {
                      title: "等待新的消息...",
                      tcp: socket.constructTCPSocketInstance(),
                      remoteip:'none',
                      localip:'none',
                      msg:"A NEW WORLD",
                      udp:socket.constructUDPSocketInstance(),
                  },
                  onInit() {
                    this.getIpAddress();
                    this.creatScoket();
                    this.title="暂无新消息"
                  },
                  //创建udpSocket 默认端口10006
                  creatScoket: async function(){
                      this.udp.bind({address: this.getIpAddress(), port: 10006, family: 1}, err => {
                          if (err) {
                              console.info('bind fail');
                              this.title='bind fail'
                              return;
                          }
                          this.title='bind success';
                          console.info('bind success');
                      })
              //          this.tcp.bind({address: this.localip, port: 10006,family: 1}, err => {
              //            if (err) {
              //                console.log('bind fail');
              //                this.title='bind fail';
              //                return;
              //            }
              //            this.title='bind success';
              //            console.log('bind success');
              //        })
                      //监听收到的信息 打印到屏幕上
                     this.udp.on('message', value => {
                         let buffer = value.message;
                         let dataView = new DataView(buffer);
                         let str = "";
                         for (let i = 0;i < dataView.byteLength; ++i) {
                             str += String.fromCharCode(dataView.getUint8(i))
                         }
                         this.title =str;
                      });
                  },
                  sendMessage: async function(){
              //        let promise1 = this.udp.connect({ address: {address: this.remoteip, port: 10006, family: 1} , timeout: 6000});
              //        promise1.then(() => {
              //            console.log('connect success');
              //            let promise2 =this.udp.send({
              //                data:this.msg
              //            });
              //            promise2.then(() => {
              //                console.log('send success');
              //            }).catch(err => {
              //                console.log('send fail');
              //            });
              //        }).catch(err => {
              //            this.title='connect fail';
              //            console.log('connect fail');
              //        });
                      //发送信息
                      let promise = this.udp.send({
                          data:this.msg,
                          address: {
                              address:this.remoteip,
                              port:10006,
                              family:1
                          }
                      });
                      promise.then(() => {
                          this.title='send success';
                          console.info('send success');
                      }).catch(err => {
                          this.title='send fail'
                          console.info('send fail');
                      });
                  },
                  newlocalip(e){
                     this.localip = e.value;
                      this.title = e.value;
                  },
                  newremoteip(e){
                      this.remoteip = e.value;
                  },
                  newMessage(e){
                      this.msg=e.value;
                      this.title=e.value;
                  },
                  //获取本机ip地址
                  getIpAddress(){
                     let ip=wifi.getIpInfo().ipAddress;
                     this.localip = (ip >> 24 & 0xFF)+"."+ ((ip >> 16) & 0xFF)+"."+((ip >> 8) & 0xFF)+"."+(ip & 0xFF);
                  },
              }
              

              3.测试

              这里为了便于测试,我们最好下载一个网络调试助手

              网络调试助手

              3.1结果

              • OpenHarmony侧

                OpenHarmony与HarmonyOS实现信息交流(一),2.gif,第4张

              • HarmonyOS侧

                OpenHarmony与HarmonyOS实现信息交流(一),3.gif,第5张

              • OpenHarmony&HarmonyOS 联动

                OpenHarmony与HarmonyOS实现信息交流(一),3b58690cc4f7008af51012d0b83be9592022614200511.gif,第6张

                4 结语

                实现了OpenHarmony与HarmonyOS的简单通讯后,应用开发,软硬件联动都有了更多的可能性。目前可能存在一些稳定性,不完整性问题,未来两侧基础功能不断完善之后,将会变得更有趣也更好用。如有明显错误,希望读者能够积极提出,我会尽力完善。

网友评论

搜索
最新文章
热门文章
热门标签
 
 梦册网七星彩梦册查码解梦  梦见和已故的亲人说话  梦到别人拿刀捅人见血