编程知识 cdmana.com

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

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个字节32bit
  • 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当然我们可以通过电脑的计算器来计算二进制

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

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 协议如下:

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

这里需要解释下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.

//magic
byte[] magicB = {‘D’, ‘H’};
 //协议版本1.0转成int也就是1
byte[] versionB = {0, 1};
//扩展数据长度,这里假定扩展数据的长度为67
byte[] extLenB = intTo4Bytes(67);
//扩展数据类型 0:JSON、1:二进制数据;这里使用JSON
byte[] 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;

总结

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。下面资料部分截图是我花费几个月时间整理的,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

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

版权声明
本文为[mb61c1dbbb44788]所创,转载请带上原文链接,感谢
https://blog.51cto.com/u_15466190/4928923

Scroll to Top