ProtoBuf 基本使用

一、是什么

Protocol Buffers,是Google公司开发的一种数据描述语言,是一种平台无关、语言无关、可扩展且类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。

二、为什么

  1. 更简单
  2. 数据描述文件只需原来的1/10至1/3
  3. 解析速度是原来的20倍至100倍
  4. 减少了二义性
  5. 生成了更容易在编程中使用的数据访问类且支持多种编程语言

三、支持的语言

Language Source
C++ (include C++ runtime and protoc) src
Java java
Python python
Objective-C objectivec
C# csharp
JavaScript js
Ruby ruby
Go golang/protobuf
PHP php
Dart dart-lang/protobuf

四、Android 中使用

4.1 添加依赖

protobuf 插件

plugins {
    ...

    // protobuf 插件, AS 3.x 需要 0.8.2 及以上
    id 'com.google.protobuf' version '0.8.17'
}

AS 3.x对应的protoBuf版本必须不低于0.8.2,否则报错 Resolving configuration 'debugCompile' directly is not allowed

模块添加依赖


android {
    ...
    sourceSets {
        main {
            // 配置 proto 源文件目录, 可选的, 默认在 'src/main/proto'
            proto {
                srcDir 'src/main/proto'
            }
        }
    }
}

dependencies {
    ...

    // protobuf
    implementation  "com.google.protobuf:protobuf-javalite:3.18.0"
}

protobuf {
    // Configures the Protobuf compilation and the protoc executable
    protoc {
        // Downloads from the repositories
        artifact = "com.google.protobuf:protoc:3.14.0"
    }

    // Generates the java Protobuf-lite code for the Protobufs in this project
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                // Configures the task output type
                java {
                    // Java Lite has smaller code size and is recommended for Android
                    option 'lite'
                }
            }
        }
    }
}

4.2 创建源文件

在对应源文件目录下面,创建文件。

如图:

文件内容如下:

syntax = "proto3";  // protobuf2 和 protobuf3 有区别

option java_package = "com.xyz.test";  // 指定生成的类的包名
option java_multiple_files = true;  // 是否为每个类单独生成一个文件

// 类
message Pet {
    int32 id = 0x01;
    repeated Dog dogs = 0x02;
    map<string, Cat> cats = 0x03;
}

message Dog {
    string name = 0x01;
    int32 age = 0x02;
}

message Cat {
    string name = 0x01;
    int32 age = 0x02;
    string food = 0x03;
}

支持
枚举 enum
List: repeated
Map: map
更多数据结构请查阅官方文档。

4.3 编译源文件

build 之后,生成的代码如下:

可以点开查看对应代码。

建议:大型项目中,为了加快编译速度,可以将 pb 文件单独作为一个模块。

4.4 序列化与反序列化

val dog1 = Dog.newBuilder().setName("小黑").setAge(5).build()
val dog2 = Dog.newBuilder().setName("旺财").setAge(3).build()
val cat1 = Cat.newBuilder().setName("小花").setAge(4).setFood("猫粮").build()
val cat2 = Cat.newBuilder().setName("猫精").setAge(1000).setFood("人").build()

val pet = Pet.newBuilder().setId(1)
    .putCats("凡间", cat1)
    .putCats("妖界", cat2)
    .addDogs(dog1)
    .addDogs(dog2)
    .build()

val toByteArray = pet.toByteArray()


val result: Pet? = try {
    Pet.parseFrom(petArray)
} catch (ex: InvalidProtocolBufferException) {
    Log.d(TAG, "parseData exception: ${ex.message}")
    null
}

更多使用方法,请查阅官网文档和相应的 API

posted @ 2023-04-08 16:15  SharpCJ  阅读(268)  评论(0编辑  收藏  举报