更多信息请访问:Harmonyos技术社区https://harmonyos.51cto.com,与华为官方共同建立关于App与IOT设备的通信,本节主要对关键通信技术进行了详细描述。考虑到TCP/UDP协议的特点,两者之间通过UDP进行通信是必然的选择。UDP是一种无连接协议。具有资源消耗低、处理速度快等优点。了解UDP是如何通信的,也是每个HarmonyOS开发者都需要了解的重点知识。下面简单介绍核心类DatagramSocket、DatagramPacket、EventHandler:1.DatagramSocket:构造函数DatagramSocket(intport,InetAddressladdr):创建DatagramSocket实例,将对象绑定到指定IP地址和指定端口。主要方法receive(DatagramPacketp):从DatagramSocket接收数据报,send(DatagramPacketp):用DatagramSocket对象发送数据报。2.DatagramPacket:构造函数DatagramPacket(byte[]buf,intlength,InetAddressaddr,intport):创建一个包含数据的数组的DatagramPacket对象,创建DatagramPacket对象时指定IP地址和端口——这是确定目的地的数据报。3.EventHandler:是HarmonyOS用来处理线程间通信的一种机制。通过EventRunner可以创建一个新线程,在新线程上执行耗时操作。这样就不会阻塞原来的线程,可以合理的处理任务。例如:主线程使用EventHandler创建子线程,子线程做耗时的图片下载操作。下载完成后,子线程通过EventHandler通知主线程,主线程更新UI。功能介绍通过AppDemo控制小车的运动(前进、后退、左转、右转、停止),主要通过UDP包发送指令,说明它们之间是如何通信的。它们之间的控制命令以json格式发送。如:"mode":"CarControl",//控制指令分类"cmd":"forward"//具体指令}。开发指南1.创建UDP协议的发送命令对象privateUdpManager(){try{mGpsDatagramSocket=newDatagramSocket();}catch(SocketExceptione){e.printStackTrace();}}2.将要发送的数据封装成DatagramPacket对象发送DatagramPacketsRequest=newDatagramPacket(mInfoArray,mInfoArray.length,InetAddress.getByName(getIp()),PORT);//开始发送mGpsDatagramSocket.send(sRequest);3.构造发送命令publicvoidsendMessage(Stringinfo){Gsongson=newGson();WifiCommandmessageInfo=newWifiCommand();messageInfo.setCmd(info);//控件类型messageInfo.setMode();//转换为jsonStringresultJson=gson.toJson(messageInfo);//创建发送命令SendMessageRunnable对象mSendMessageRunnable=newSendMessageRunnable();mSendMessageRunnable.setInfoArray(resultJson.getBytes(StandardCharsets.UTF_8));//开始发送命令线程mEventHandler.postTask(mSendMessageRunnable);if("stop".equals(info)||"tripod_on".equals(info)||"tripod_off".equals(info)){HiLog.info(label,"info="+info);}else{//开始发送Gps请求线程和接收信息线程startReceive();startSendGpsMessage();}HiLog.info(label,"sendmessage=“+resultjson);}实现实现效果附上主要主要主要主要主要主要源代码主要主要主要主要主要源代码1.ResourceTable.Layout_ability_main);initComponent();//初始化WiFi控制对象udpManager=UdpManager.getInstance(this);}privatevoidinitComponent(){iTurnUp=(Button)findComponentById(ResourceTable.Id_i_up);iTurnUp.setClickedListener(this);iTurnDown=(按钮)findComponentById(ResourceTable.Id_i_down);iTurnDown.setClickedListener(this);iTurnLeft=(按钮)findComponentById(ResourceTable.Id_i_left);iTurnLeft.setClickedListener(this);iTurnRight=(按钮)findComponentById(ResourceTable.Id_i_right);iTurnRight。setClickedListener(this);iTurnRun=(Button)findComponentById(ResourceTable.Id_i_run);iTurnRun.setClickedListener(this);2.UdpManager/***UDP连接类*/publicclassUdpManager{privatestaticfinalHiLogLabellabel=newHiLogLabel(HiLog.LOG_APP,0x00134,"UdpManager");privatestaticfinalintPORT=48100;privatestaticfinalintGET_MESSAGE=1;privatestaticUdpManagersUdpManager;privatestaticContextsContext;privateUdpReceiveCallbackmReceiveInformationCallback;privateReceiveMessageRunnablemReceiveMessageRunnable;privateSendGpsMessageRunnablemSendGpsMessageRunnable;privateSendMessageRunnablemSendMessageRunnable;privateDatagramSocketmGpsDatagramSocket;privatestaticStringip="192.168.0.1";/***控制是否还需要接收信息控制器*/privatebooleanflag=false;privatefinalEventHandlermEventHandler=newEventHandler(EventRunner.create()){@OverrideprotectedvoidprocessEvent(InnerEventevent){super.processEvent(event);if(event.eventId)=={ifGET_MESSAGE(mReceiveInformationCallback!=null){mReceiveInformationCallback.getMessage(event.object);}}}};privatefinalEventHandlermReceiveEventHandler=newEventHandler(EventRunner.create()){};privatefinalEventHandlermSendGpsEventHandler=newEventHandler(EventRunner.create()){};/***UdpManager单例**@returnUdpManager单例对象*/publicstaticUdpManagergetInstance(Contextcontext){if(sUdpManager==null){sUdpManager=newUdpManager();sContext=context;}returnsUdpManager;}/***constructor*/privateUdpManager(){//创建一个UDP协议的发送命令对象try{mGpsDatagramSocket=newDatagramSocket();}catch(SocketExceptione){e.printStackTrace();}}/***注册接收信息回调函数**@paramcallback接收信息回调函数*/publicvoidregisterCallback(UdpReceiveCallbackcallback){mReceiveInformationCallback=callback;}/***外部发送命令方法**@paraminfo需要发送命令*/publicvoidsendMessage(Stringinfo){Gsongson=newGson();UdpCommandmessageInfo=newUdpCommand();//传入控制命令messageInfo.setCmd(info);//控制类型messageInfo.setMode();//转换为jsonStringresultJson=gson.toJson(messageInfo);//创建发送命令SendMessageRunnable对象tmSendMessageRunnable=newSendMessageRunnable();mSendMessageRunnable.setInfoArray(resultJson.getBytes(StandardCharsets.UTF_8));//开始发送命令线程mEventHandler.postTask(mSendMessageRunnable);//开始自动发送Gps请求线程和接收信息线程if("stop".equals(info)){HiLog.info(label,"info="+info);}else{//开始发送Gps请求线程和接收信息线程startReceive();startSendGpsMessage();}HiLog.info(label,"sendMessage="+resultJson);}publicStringgetIp(){returnip;}publicvoidsetIp(StringmIp){this.ip=mIp;}/***内部类,使用发送命令*/privateclassSendMessageRunnableimplementsRunnable{privatebyte[]mInfoArray;voidsetInfoArray(byte[]infoArray){mInfoArray=infoArray;}@Overridepublicvoidrun(){HiLog.info(label,"sendthread="+Thread.currentThread().getName());//发送数据try{//延迟发送50毫秒,因为不发送小车会卡住mInfoArray.length,InetAddress.getByName(getIp()),PORT);//开始发送mGpsDatagramSocket.send(sRequest);}catch(IOException|InterruptedExceptione){e.printStackTrace();HiLog.info(label,"sendMessageerror");}}}/***内部类,用于接收命令*/privateclassReceiveMessageRunnableimplementsRun启用{@Overridepublicvoidrun(){尝试{while(flag){byte[]buf=newbyte[1024];DatagramPacketreceiveDatagramPacket=newDatagramPacket(buf,buf.length);if(mGpsDatagramSocket!=null&&!mGpsDatagramSocket.isClosed()){HiLog.info(label,"接收线程启动Blocking"+Thread.currentThread().getName());//接收返回的数据会阻塞线程mGpsDatagramSocket.receive(receiveDatagramPacket);//将获取到的数据转换成jsonStringjson=newString(receiveDatagramPacket.getData(),StandardCharsets.UTF_8);json=json.substring(json.indexOf("{"),json.lastIndexOf("}")+1);HiLog.info(label,"receiveMessagejson="+json);//发送对象到需要接收返回值的地方}/***内部类,用于发送请求Gps命令*/privateclassSendGpsMessageRunnableimplementsRunnable{@Overridepublicvoidrun(){Gsongson=newGson();UdpCommandmessageInfo=newUdpCommand();//传入控制commandmessageInfo.setCmd("getinfo");//控件类型messageInfo.setMode();//转换为jsonStringresultJson=gson.toJson(messageInfo);byte[]infoArray=resultJson.getBytes(StandardCharsets.UTF_8);try{//将要发送的数据封装成一个DatagramPacket对象DatagramPacketsRequest=newDatagramPacket(infoArray,infoArray.length,InetAddress.getByName(getIp()),PORT);//开始发送mGpsDatagramSocket.send(sRequest);//开始获取Gps命令线程mSendGpsEventHandler.postTask(mSendGpsMessageRunnable,2000);HiLog.info(label,"sendgps");}catch(IOExceptione){e.printStackTrace();}}}/***开始接收消息*/privatevoidstartReceive(){if(!flag){flag=true;//创建接收命令的ReceiveMessageRunnable对象mReceiveMessageRunnable=newReceiveMessageRunnable();//开始接收命令线程mReceiveEventHandler.postTask(mReceiveMessageRunnable);HiLog.info(label,"开始接收线程");}}/***开始获取GPS点*/privatevoidstartSendGpsMessage(){//创建SendGps命令SendGpsMessageRunnable对象如果(mSendGpsMessageRunnable==null){mSendGpsMessageRunnable=newSendGpsMessageRunnable();}//开始获取Gps命令线程mSendGpsEventHandler.postTask(mSendGpsMessageRunnable);HiLog.info(label,"开始发送GPS请求线程");}3.UdpCommandclassUdpCommand{//控制命令:forward,back,left,rightprivateStringcmd;//控制类型privateStringmode;publicStringgetCmd(){returncmd;}voidsetCmd(Stringcmd){this.cmd=cmd;}publicStringgetMode(){returnmode;}voidsetMode(){this.mode="CarControl";}}4.UdpReceiveCallback/***接收小车返回数据的回调函数*/publicinterfaceUdpReceiveCallback{voidgetMessage(Objectvalue);}5.xml布局文件
