写点什么

Android 与单片机 --- 开发板 --- 智能硬件 --- 智能设备 --- 数据协议 -- 开发总结

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日

| --- | --- | --- | --- || byte | 1 | 8 | -128 ~ 127 || char | 2 | 16 | '\u0000' ~ '\uFFFF' || short | 2 | 16 | -2^15 ~ 2^15 - 1 || int | 4 | 32 | -2^31 ~ 2^31 - 1 || float | 4 | 32 | 2^-149 ~ 2^128 -1 || long | 8 | 64 | -2^63 ~ 2^63 - 1 || double | 8 | 64 | 2^-1074 ~ 2^1024 - 1 || boolean | / | 1 | true or false |


  • String 在 Java 中不属于基本数据类型,一个汉字占 2 个字节,一个英文字母占 1 个字节

  • 小结:1 byte = 8 bit

3.1 什么是 bit 呢?什么又是高低位呢?在 Java 中又怎么写代码呢?

  • bit 就是 也就是二进制数据,取值只有 0,1 - 高位在左,低位在右

  • 这里以 byte 123 为例:

  • byte b =123 转为 bit

  • 高位在 0,低位在 1 0111 1011

  • 在 Java 中获取 byte 的 8 个 bit


/**


  • byte 转 8 bit

  • @param b byte

  • @return 高位到低位顺序, 以 byte123 为例: 0111 1011*/public static byte[] byte2Bit(byte b) {byte[] arr = new byte[8];for (int i = 7; i >= 0; i--) {arr[i] = (byte) (b & 1);b = (byte) (b >> 1);}return arr;}

  • 既然把 byte 转为了 8 个 bit 位,那我们又怎么再把 bit 转回为 byte 呢?


/**


  • 8 个 bit 位转为 byte*/public static byte bit2Byte(byte[] bytes) {if (bytes.length != 8) return 0;String binary = "";byte result;for (byte b : bytes) {binary += b;}if (bytes[0] == 0) {// 正数 result = (byte) Integer.parseInt(binary, 2);} else {// 负数 result = (byte) (Integer.parseInt(binary, 2) - 256);}return result;}

3.2 上面已经说了 byte 与 bit 的相互转化,现在就轮到int

  • 上面已经说了一个int4个字节`32


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


bit`


  • Integer 类已经为我们封装好了转 bit 的方法,如下:


String s = Integer.toBinaryString(35235);//输出结果 1000100110100011


  • 可以看到没有 32 位,这是为什么呢?这是因为高位都是为0所以就直接省略了,当然我们也可以主动补齐32位只需要在高位补0即可。

  • bit 再转回为 int


int result = Integer.parseInt("1000100110100011", 2);//输出结果 35235


  • 这里需要注意的是 Integer.toBinaryString()可以将负数转化为二进制,但是 Integer.parseInt("", 2)不能直接将负数的二进制转为 int,如下:


String radix = Integer.toBinaryString(-35235);System.out.println(radix);int result = Integer.parseInt(radix, 2);System.out.println(result);


程序执行会报一个java.lang.NumberFormatException: For input string:"11111111111111110111011001011101"异常,那我们怎么将负数的转回为 int 呢?当然是有方法的啦,如下:


//需要借助 BigInteger 类 String radix = Integer.toBinaryString(-3535);BigInteger integer = new BigInteger(radix, 2);System.out.println(integer.intValue());//输出结果-3535

3.3 当然我们可以通过电脑的计算器来计算二进制

3.4 上面我们说了一个int32个字节也就是4byte,那理所当然一个int可以转成 2 个 byte 或者4byte,如下:

/**


  • 一个 int 转 2 个字节的 byte 数组

  • 由低位到高位的转换

  • @param value

  • @return*/public static byte[] intTo2Bytes(int value) {byte[] src = new byte[2];src[0] = (byte) (value & 0xFF);src[1] = (byte) ((value >> 8) & 0xFF);return src;}


/**


  • 一个 int 转 4 个字节的 byte 数组

  • 由低位到高位的转换

  • @param value

  • @return*/public static byte[] intTo4Bytes(int value) {byte[] src = new byte[4];src[0] = (byte) (value & 0xFF);src[1] = (byte) ((value >> 8) & 0xFF);src[2] = (byte) ((value >> 16) & 0xFF);src[3] = (byte) ((value >> 24) & 0xFF);return src;}


这里需要注意的是int转byte[]的时候是高位数组的0下标 还是低位数组的0下标,上面的两个方法都是低位在数组的0下标

四、上面 bb 了一大堆,现在我们通过一个具体的协议来深入了解这些内容

4.1 协议如下:


这里需要解释下ucharuint是什么意思?uchar = unsigned char 、uint = unsigned int,也就是无符号的数据,也就是表示了这个数据是正数


  • 1、对协议进行分析可以得知:整个数据包是由两部分组成的包头+扩展数据包,其中包头占固定的 32 个字节

  • 2、首先我们得分析包头里面的每一个字段所占了多少个字节

  • uchar 占 1 个字节

  • uint 占 4 个字节

  • 2、那我们重点就是得来分析包头的数据需要怎么封装,通过协议我们可以看出包头内一共包含 6 个字段,分别表示如下:

  • 第一个为固定的"DH",总共占2个字节

  • 第二个为版本1.0 ,总共占2个字节

  • 第三个为扩展数据长度"extlen" ,总共占4个字节

  • 第四个为扩展数据类型取值0或1 ,总共占1个字节

  • 第五个为保留字段不使用就0补齐,总共占3个字节

  • 第六个为保留字段不使用就0补齐,总共占20个字节

  • 3、通过上面一顿分析,我们就轻松的理清了每个字段所占的字节了

4.2 Talk is cheap. Show me the code.

//magicbyte[] magicB = {'D', 'H'};//协议版本 1.0 转成 int 也就是 1byte[] versionB = {0, 1};//扩展数据长度,这里假定扩展数据的长度为 67byte[] extLenB = intTo4Bytes(67);//扩展数据类型 0:JSON、1:二进制数据;这里使用 JSONbyte[] extType = {0};//两个保留字段,直接 0 补齐,上面已经分析了两个字段一共占 23 个字节 byte[] reserved = new byte[23];//这里将上面的多个数据合并至一个 byte[]byte[] data = byteMergerAll(magicB, versionB, extLenB, extType, reserved);


到这里包头的数据就已经处理好了,还可以进一步对它进行封装


  • 这里提供一个多个数据数组合并的工具方法


/**


  • 多个数组合并一个

  • @return*/public static byte[] byteMergerAll(byte[]... bytes) {int allLength = 0;for (byte[] b : bytes) {allLength += b.length;}byte[] allByte = new byte[allLength];int countLength = 0;for (byte[] b : bytes) {System.arraycopy(b, 0, allByte, countLength, b.length);countLength += b.length;}return allByte;}

4.3 封装包头数据

/**


  • 封装包头数据

  • 固定 32 个字节,其余的 0 补齐

  • @param extLen 扩展数据长度*/public static byte[] getPkgHead(int extLen) {//magicbyte[] magicB = {'D', 'H'};//协议版本 1.0 转成 int 也就是 1byte[] versionB = {0, 1};//扩展数据长度,这里假定扩展数据的长度为 67

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android与单片机---开发板---智能硬件---智能设备---数据协议--开发总结