Android:使用protobuf数据通讯

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情

前言

在之前的某个项目开发中被告知,该模块的通讯方式是通过protobuf方式。这是什么东西,怎么闻所未闻?平时的开发中基本都是使用json解析,简单方便。再一个就是听说过使用xml解析,也从来没使用过,今天遇到一个从来不知道的解析方式,那就让我们一探究竟吧。

protobuf简介

protobuf (protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),类似于XML能够将结构化数据序列化,用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

如何使用

它的引入稍微复杂些,其中包含插件,通过一些配置自动生成一些必要的代码。
首先配置插件,在项目根目录build.gradle下做如下配置

dependencies {
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.13'
}

接着在app模块下build.gradle做如下配置

plugins {
    id 'com.google.protobuf'
}
protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.5.1' // 也可以配置本地编译器路径
    }
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                remove java
            }
            task.builtins {
                java {}// 生产java源码
            }
        }
    }
}

android{
   sourceSets {
        main {
            proto {
                srcDir '../src/main/proto' //指定.proto文件路径
            }
            java {
                srcDir '../src/main/java'
            }
        }
    }
}

implementation "com.google.protobuf:protobuf-java:3.5.1"
implementation "com.google.protobuf:protoc:3.5.1"

完成上述配置之后,执行一下rebuild方法,我们就能够自动生成proto java class文件了。
接下来就是新建.proto实体文件,相当于实体类:

message Person {
    required string name = 1;//required 消息体中必填字段,不设置会导致编解码异常
    repeated int32 id = 2;//repeated消息体中可选字段,可通过default关键字设置默认值
    repeated string email = 3;//repeated消息体中可重复字段,重复的值的顺序会被保留
}

我们可以看到每个属性后面都有一个数字,没错,这个很关键。在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0,2^29-1]范围内的一个整数。如果出现重复标识,解析必定会失败。其中的数据类型和java几乎无异,但有个需要注意的是int有int32和int64之分。实体内属性的排序也很重要,需要和后端一一对用,最好是共用一个文件,否则很可能出现匹配不上导致解析错误。

如何生成实体和解析实体呢?

val array: BaseProto.Person = BaseProto.Person.newBuilder()
    .setName("张三")
    .setid(1)
    .setEmail("123")
    .build()
    .toByteArray()

这样就生成了基于protobuf加密的Byte数组数据,解析也非常简单:

val byteArray = getData()
val protoData: BaseProto.Person = BaseProto.Person.parseFrom(byteArray)

解析到实体后使用就和平常json解析拿到实体一样了,对于开发者来说流程确实稍显复杂了些,其中大量的配置和实体的定义稍微不注意或者后端更改了实体后就会直接解析失败,初次使用可能会调试很久,获取到的数据都是一些byte数组,如果不转换为定义的实体就看不到真实的数据。

总结

protobuf的优点在于解析速度快,适用于一些传输大量数据的场景,数据源也进行了一些加密。有优点就有缺点,配置确实很麻烦,特别是实体编写环节稍不注意就容易和后端实体无法匹配导致解析失败。后端更改实体的同时,移动端也需要同步修改,否则也无法解析成功。所以在无特殊情况下,建议还是使用json解析,操作方便、简洁。只能说多了解一项解析能力也是一件好事,说不定以后还会用上呢。

以上便是Android中使用protobuf数据通讯的所有知识,希望对大家有所帮助!

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情