自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于HarmonyOS控制Hi3861小車之信息通信

開發(fā) 前端 OpenHarmony
本節(jié)主要詳細(xì)講述一下通信關(guān)鍵技術(shù),考慮到TCP/UDP協(xié)議的特性,兩者間通過UDP進(jìn)行通信是一種必然的選擇,UDP一種無連接的協(xié)議。

[[422670]]

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

引言

在鴻蒙應(yīng)用實際開發(fā)中,經(jīng)常會遇到App與IOT設(shè)備間的通信,本節(jié)主要詳細(xì)講述一下通信關(guān)鍵技術(shù),考慮到TCP/UDP協(xié)議的特性,兩者間通過UDP進(jìn)行通信是一種必然的選擇,UDP一種無連接的協(xié)議,具有資源消耗小,處理速度快的優(yōu)點,了解UDP是怎么通信的,這對于每一個HarmonyOS開發(fā)者也是需要了解的重點知識。

核心類

DatagramSocket、DatagramPacket、EventHandler,下面分別簡單介紹下:

1.DatagramSocket:

構(gòu)造器DatagramSocket(int port, InetAddress laddr):創(chuàng)建一個DatagramSocket實例,并將該對象綁定到指定IP地址、指定端口。主要方法receive(DatagramPacket p):從該DatagramSocket中接收數(shù)據(jù)報,send(DatagramPacket p):以該DatagramSocket對象向外發(fā)送數(shù)據(jù)報。

2.DatagramPacket:

構(gòu)造器DatagramPacket(byte[] buf, int length, InetAddress addr, int port):以一個包含數(shù)據(jù)的數(shù)組來創(chuàng)建DatagramPacket對象,創(chuàng)建該DatagramPacket對象時還指定了IP地址和端口--這就決定了該數(shù)據(jù)報的目的地。

3.EventHandler:

是HarmonyOS用于處理線程間通信的一種機(jī)制,可以通過EventRunner創(chuàng)建新線程,將耗時的操作放到新線程上執(zhí)行。這樣既不阻塞原來的線程,任務(wù)又可以得到合理的處理。比如:主線程使用EventHandler創(chuàng)建子線程,子線程做耗時的下載圖片操作,下載完成后,子線程通過EventHandler通知主線程,主線程再更新UI。

功能介紹

通過App Demo控制小車運(yùn)動(前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn)、停止),主要通過UDP數(shù)據(jù)包發(fā)送命令,來說明它們間是怎么通信的,它們間控制命令以json格式發(fā)送。

如:

  1. "mode""CarControl",//控制命令分類 
  2.     "cmd""forward"//具體命令 
  3. }。 

開發(fā)指南

1、創(chuàng)建UDP協(xié)議的發(fā)送命令對象

  1. private UdpManager() { 
  2.         try { 
  3.             mGpsDatagramSocket = new DatagramSocket(); 
  4.         } catch (SocketException e) { 
  5.             e.printStackTrace(); 
  6.         } 
  7.     } 

2、將要發(fā)送的數(shù)據(jù)封裝成DatagramPacket對象發(fā)送

  1. DatagramPacket sRequest = new DatagramPacket(mInfoArray, mInfoArray.length, 
  2. InetAddress.getByName(getIp()), PORT); 
  3. // 開始發(fā)送 
  4. mGpsDatagramSocket.send(sRequest); 

3、構(gòu)造發(fā)送的命令

  1. public void sendMessage(String info) { 
  2.         Gson gson = new Gson(); 
  3.         WifiCommand messageInfo = new WifiCommand(); 
  4.         messageInfo.setCmd(info); 
  5.         //控制類型 
  6.         messageInfo.setMode(); 
  7.         //轉(zhuǎn)換成json 
  8.         String resultJson = gson.toJson(messageInfo); 
  9.         // 創(chuàng)建發(fā)送命令SendMessageRunnable對象 
  10.         mSendMessageRunnable = new SendMessageRunnable(); 
  11.         mSendMessageRunnable.setInfoArray(resultJson.getBytes(StandardCharsets.UTF_8)); 
  12.         // 啟動發(fā)送命令線程 
  13.         mEventHandler.postTask(mSendMessageRunnable); 
  14.         if ("stop".equals(info) || "tripod_on".equals(info) || "tripod_off".equals(info)){ 
  15.             HiLog.info(label, "info = " + info); 
  16.         } else { 
  17.             // 啟動發(fā)送Gps請求線程和接收信息線程 
  18.             startReceive(); 
  19.             startSendGpsMessage(); 
  20.         } 
  21.         HiLog.info(label, "sendMessage = " + resultJson); 
  22.     } 

實現(xiàn)效果

基于HarmonyOS控制Hi3861小車之信息通信-鴻蒙HarmonyOS技術(shù)社區(qū)

附上主要源代碼

1. MainAbilitySlice

  1. public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener{ 
  2.     private Button iTurnUp,iTurnDown,iTurnLeft,iTurnRight,iTurnRun; 
  3.  
  4.     private UdpManager udpManager; 
  5.     @Override 
  6.     public void onStart(Intent intent) { 
  7.         super.onStart(intent); 
  8.         super.setUIContent(ResourceTable.Layout_ability_main); 
  9.         initComponent(); 
  10.         // 初始化WiFi控制對象 
  11.         udpManager = UdpManager.getInstance(this); 
  12.     } 
  13.  
  14.     private void initComponent(){ 
  15.         iTurnUp = (Button) findComponentById(ResourceTable.Id_i_up); 
  16.         iTurnUp.setClickedListener(this); 
  17.  
  18.         iTurnDown = (Button) findComponentById(ResourceTable.Id_i_down); 
  19.         iTurnDown.setClickedListener(this); 
  20.  
  21.         iTurnLeft = (Button) findComponentById(ResourceTable.Id_i_left); 
  22.         iTurnLeft.setClickedListener(this); 
  23.  
  24.         iTurnRight = (Button) findComponentById(ResourceTable.Id_i_right); 
  25.         iTurnRight.setClickedListener(this); 
  26.  
  27.         iTurnRun = (Button) findComponentById(ResourceTable.Id_i_run); 
  28.         iTurnRun.setClickedListener(this); 

 2. UdpManager

  1. /** 
  2.  * UDP連接類 
  3.  */ 
  4. public class UdpManager { 
  5.     private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00134, "UdpManager"); 
  6.     private static final int PORT = 48100; 
  7.     private static final int GET_MESSAGE = 1; 
  8.     private static UdpManager sUdpManager; 
  9.     private static Context sContext; 
  10.     private UdpReceiveCallback mReceiveInformationCallback; 
  11.     private ReceiveMessageRunnable mReceiveMessageRunnable; 
  12.     private SendGpsMessageRunnable mSendGpsMessageRunnable; 
  13.     private SendMessageRunnable mSendMessageRunnable; 
  14.     private DatagramSocket mGpsDatagramSocket; 
  15.     private static  String ip = "192.168.0.1"
  16.  
  17.     /** 
  18.      * 控制是否還需要接收信息控制器 
  19.      */ 
  20.     private boolean flag = false
  21.  
  22.     private final EventHandler mEventHandler = new EventHandler(EventRunner.create()) { 
  23.         @Override 
  24.         protected void processEvent(InnerEvent event) { 
  25.             super.processEvent(event); 
  26.             if (event.eventId == GET_MESSAGE) { 
  27.                 if (mReceiveInformationCallback != null) { 
  28.                     mReceiveInformationCallback.getMessage(event.object); 
  29.                 } 
  30.             } 
  31.         } 
  32.     }; 
  33.  
  34.     private final EventHandler mReceiveEventHandler = new EventHandler(EventRunner.create()) { 
  35.     }; 
  36.  
  37.     private final EventHandler mSendGpsEventHandler = new EventHandler(EventRunner.create()) { 
  38.     }; 
  39.  
  40.     /** 
  41.      * UdpManager的單例 
  42.      * 
  43.      * @return UdpManager單例對象 
  44.      */ 
  45.     public static UdpManager getInstance(Context context) { 
  46.         if (sUdpManager == null) { 
  47.             sUdpManager = new UdpManager(); 
  48.             sContext = context; 
  49.         } 
  50.         return sUdpManager; 
  51.     } 
  52.  
  53.     /** 
  54.      * 構(gòu)造函數(shù) 
  55.      */ 
  56.     private UdpManager() { 
  57.         // 創(chuàng)建UDP協(xié)議的發(fā)送命令對象 
  58.         try { 
  59.             mGpsDatagramSocket = new DatagramSocket(); 
  60.         } catch (SocketException e) { 
  61.             e.printStackTrace(); 
  62.         } 
  63.     } 
  64.  
  65.     /** 
  66.      * 注冊接收信息的回調(diào)函數(shù) 
  67.      * 
  68.      * @param callback 接收信息回調(diào)函數(shù) 
  69.      */ 
  70.     public void registerCallback(UdpReceiveCallback callback) { 
  71.         mReceiveInformationCallback = callback; 
  72.     } 
  73.  
  74.     /** 
  75.      * 對外提供的發(fā)送命令方法 
  76.      * 
  77.      * @param info 需要發(fā)送的命令 
  78.      */ 
  79.     public void sendMessage(String info) { 
  80.         Gson gson = new Gson(); 
  81.         UdpCommand messageInfo = new UdpCommand(); 
  82.  
  83.         // 傳進(jìn)來的控制命令 
  84.         messageInfo.setCmd(info); 
  85.  
  86.         //控制類型 
  87.         messageInfo.setMode(); 
  88.  
  89.         //轉(zhuǎn)換成json 
  90.         String resultJson = gson.toJson(messageInfo); 
  91.  
  92.         // 創(chuàng)建發(fā)送命令SendMessageRunnable對象 
  93.         mSendMessageRunnable = new SendMessageRunnable(); 
  94.         mSendMessageRunnable.setInfoArray(resultJson.getBytes(StandardCharsets.UTF_8)); 
  95.  
  96.         // 啟動發(fā)送命令線程 
  97.         mEventHandler.postTask(mSendMessageRunnable); 
  98.  
  99.         // 啟動發(fā)送Gps請求線程和接收信息線程 
  100.         if ("stop".equals(info)) { 
  101.             HiLog.info(label, "info = " + info); 
  102.         } else { 
  103.             // 啟動發(fā)送Gps請求線程和接收信息線程 
  104.             startReceive(); 
  105.             startSendGpsMessage(); 
  106.         } 
  107.         HiLog.info(label, "sendMessage = " + resultJson); 
  108.     } 
  109.  
  110.     public String getIp() { 
  111.         return ip; 
  112.     } 
  113.  
  114.  
  115.     public void setIp(String mIp) { 
  116.         this.ip = mIp; 
  117.     } 
  118.  
  119.     /** 
  120.      * 內(nèi)部類,用作發(fā)送命令 
  121.      */ 
  122.     private class SendMessageRunnable implements Runnable { 
  123.         private byte[] mInfoArray; 
  124.  
  125.         void setInfoArray(byte[] infoArray) { 
  126.             mInfoArray = infoArray; 
  127.         } 
  128.  
  129.         @Override 
  130.         public void run() { 
  131.             HiLog.info(label, "發(fā)送線程 = " + Thread.currentThread().getName()); 
  132.  
  133.             // 發(fā)送數(shù)據(jù) 
  134.             try { 
  135.                 // 延時發(fā)送50毫秒,因為如果不延時會將小車卡死 
  136.                 Thread.sleep(50); 
  137.  
  138.                 // 將要發(fā)送的數(shù)據(jù)封裝成DatagramPacket對象 
  139.                 DatagramPacket sRequest = new DatagramPacket(mInfoArray, mInfoArray.length, 
  140.                         InetAddress.getByName(getIp()), PORT); 
  141.  
  142.                 // 開始發(fā)送 
  143.                 mGpsDatagramSocket.send(sRequest); 
  144.             } catch (IOException | InterruptedException e) { 
  145.                 e.printStackTrace(); 
  146.                 HiLog.info(label, "sendMessage error"); 
  147.             } 
  148.         } 
  149.     } 
  150.  
  151.     /** 
  152.      * 內(nèi)部類,用作接收命令 
  153.      */ 
  154.     private class ReceiveMessageRunnable implements Runnable { 
  155.  
  156.         @Override 
  157.         public void run() { 
  158.             try { 
  159.                 while (flag) { 
  160.                     byte[] buf = new byte[1024]; 
  161.                     DatagramPacket receiveDatagramPacket = new DatagramPacket(buf, buf.length); 
  162.                     if (mGpsDatagramSocket != null && !mGpsDatagramSocket.isClosed()) { 
  163.                         HiLog.info(label, "接收線程開始阻塞" + Thread.currentThread().getName()); 
  164.  
  165.                         // 接收返回數(shù)據(jù),會阻塞線程 
  166.                         mGpsDatagramSocket.receive(receiveDatagramPacket); 
  167.  
  168.                         // 將得到的數(shù)據(jù)轉(zhuǎn)成json 
  169.                         String json = new String(receiveDatagramPacket.getData(), StandardCharsets.UTF_8); 
  170.                         json = json.substring(json.indexOf("{"), json.lastIndexOf("}")+1); 
  171.                         HiLog.info(label, "receiveMessage json = " + json); 
  172.  
  173.                         // 將對象發(fā)送給需要接收返回值的地方 
  174.                         mEventHandler.sendEvent(InnerEvent.get(GET_MESSAGE, json)); 
  175.                     } 
  176.                 } 
  177.             } catch (IOException e) { 
  178.                 e.printStackTrace(); 
  179.                 HiLog.error(label, "receiveMessage error"); 
  180.             } 
  181.         } 
  182.     } 
  183.  
  184.     /** 
  185.      * 內(nèi)部類,用作發(fā)送請求Gps命令 
  186.      */ 
  187.     private class SendGpsMessageRunnable implements Runnable { 
  188.  
  189.         @Override 
  190.         public void run() { 
  191.             Gson gson = new Gson(); 
  192.             UdpCommand messageInfo = new UdpCommand(); 
  193.  
  194.             // 傳進(jìn)來的控制命令 
  195.             messageInfo.setCmd("getinfo"); 
  196.  
  197.             //控制類型 
  198.             messageInfo.setMode(); 
  199.  
  200.             //轉(zhuǎn)換成json 
  201.             String resultJson = gson.toJson(messageInfo); 
  202.  
  203.             byte[] infoArray = resultJson.getBytes(StandardCharsets.UTF_8); 
  204.  
  205.             try { 
  206.                 // 將要發(fā)送的數(shù)據(jù)封裝成DatagramPacket對象 
  207.                 DatagramPacket sRequest = new DatagramPacket(infoArray, infoArray.length, 
  208.                         InetAddress.getByName(getIp()), PORT); 
  209.  
  210.                 // 開始發(fā)送 
  211.                 mGpsDatagramSocket.send(sRequest); 
  212.  
  213.                 // 啟動獲取Gps命令線程 
  214.                 mSendGpsEventHandler.postTask(mSendGpsMessageRunnable, 2000); 
  215.                 HiLog.info(label, "發(fā)送gps"); 
  216.             } catch (IOException e) { 
  217.                 e.printStackTrace(); 
  218.             } 
  219.         } 
  220.     } 
  221.  
  222.     /** 
  223.      * 啟動接收消息 
  224.      */ 
  225.     private void startReceive() { 
  226.         if (!flag) { 
  227.             flag = true
  228.  
  229.             // 創(chuàng)建接收命令ReceiveMessageRunnable對象 
  230.             mReceiveMessageRunnable = new ReceiveMessageRunnable(); 
  231.  
  232.             // 啟動接收命令線程 
  233.             mReceiveEventHandler.postTask(mReceiveMessageRunnable); 
  234.             HiLog.info(label, "開啟接收線程"); 
  235.         } 
  236.     } 
  237.  
  238.     /** 
  239.      * 開始獲取gps點 
  240.      */ 
  241.     private void startSendGpsMessage() { 
  242.         // 創(chuàng)建發(fā)送Gps命令SendGpsMessageRunnable對象 
  243.         if (mSendGpsMessageRunnable == null) { 
  244.             mSendGpsMessageRunnable = new SendGpsMessageRunnable(); 
  245.         } 
  246.  
  247.         // 啟動獲取Gps命令線程 
  248.         mSendGpsEventHandler.postTask(mSendGpsMessageRunnable); 
  249.         HiLog.info(label, "開啟發(fā)送gps請求線程"); 
  250.     } 

 3. UdpCommand

  1. class UdpCommand { 
  2.     // 控制命令:forward,back,left,right 
  3.     private String cmd; 
  4.     // 控制類型 
  5.     private String mode; 
  6.  
  7.     public String getCmd() { 
  8.         return cmd; 
  9.     } 
  10.  
  11.     void setCmd(String cmd) { 
  12.         this.cmd = cmd; 
  13.     } 
  14.  
  15.     public String getMode() { 
  16.         return mode; 
  17.     } 
  18.  
  19.     void setMode() { 
  20.         this.mode = "CarControl"
  21.     } 

 4. UdpReceiveCallback

  1. /** 
  2.  * 接收小車返回數(shù)據(jù)的回調(diào)函數(shù) 
  3.  */ 
  4. public interface UdpReceiveCallback { 
  5.     void getMessage(Object value); 

 5. 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:alignment="center" 
  7.     ohos:orientation="vertical"
  8.  
  9.     <DirectionalLayout 
  10.         ohos:height="70vp" 
  11.         ohos:width="match_parent" 
  12.         ohos:orientation="horizontal" 
  13.         ohos:layout_alignment="center" 
  14.         ohos:top_margin="10vp" > 
  15.         <Button 
  16.             ohos:id="$+id:i_up" 
  17.             ohos:height="50vp" 
  18.             ohos:width="120vp" 
  19.             ohos:background_element="#FF9F9F9F" 
  20.             ohos:left_margin="60vp" 
  21.             ohos:text_size="25fp" 
  22.             ohos:text="前進(jìn)"/> 

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2020-11-03 11:39:22

wifi小車

2020-10-30 09:41:44

鴻蒙Hi3861WiFi小車

2022-03-15 15:00:59

Hi3861Pin接口鴻蒙

2023-07-25 10:42:39

鴻蒙遙控3861小車

2020-10-16 09:50:37

Hi3861WiFi熱點

2022-05-30 15:21:27

Hi3861TCP通信

2023-05-26 16:07:14

Hi3861Wifi模塊

2021-09-16 10:03:39

鴻蒙HarmonyOS應(yīng)用

2022-09-07 15:35:49

設(shè)備開發(fā)鴻蒙

2020-10-14 09:41:02

Hi3861GPIO點燈

2020-12-17 10:02:16

鴻蒙Hi3861開發(fā)板

2021-02-02 15:52:17

鴻蒙HarmonyOS應(yīng)用開發(fā)

2020-11-06 10:15:16

HiBurn

2020-10-28 10:00:09

海思Hi3861CentOS鴻蒙LiteOS

2021-04-25 10:06:57

鴻蒙HarmonyOS應(yīng)用

2020-11-02 12:07:11

鴻蒙 GPIO

2020-12-31 12:02:15

鴻蒙Hi3861環(huán)境搭建

2020-12-11 12:45:04

鴻蒙Hi3861游戲

2020-12-15 11:57:49

Hi3861 HarmonyOS開發(fā)板

2020-11-30 13:57:48

Hi3861
點贊
收藏

51CTO技術(shù)棧公眾號