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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章