在AndroidStudio中搭建Protobuf

什么是Protobuf

官方文檔給出的是:
a language-neutral, platform-neutral, extensible way of serializing structured data for use in communications protocols, data storage, and more.

Protobuf的優(yōu)點(diǎn)

1,性能好,效率高

2,代碼生成機(jī)制,數(shù)據(jù)解析類自動生成

3,支持向后兼容和向前兼容

4,支持多種編程語言(java,c++,python)

5,參考文檔:http://blog.csdn.net/caisini_vc/article/details/5599468

Protobuf的缺點(diǎn)

1, 應(yīng)用不夠廣

2, 二進(jìn)制格式導(dǎo)致可讀性差(二進(jìn)制格式)

3, 缺乏自描述

官方文檔描述如下:for instance, protocol buffers would not be a good way to model a text-based document with markup (e.g. HTML), since you cannot easily interleave structure with text

4, 參考文檔:http://blog.csdn.net/caisini_vc/article/details/5599468

核心概念

1,.proto文件

相當(dāng)于確定數(shù)據(jù)協(xié)議,數(shù)據(jù)結(jié)構(gòu)中存在哪些數(shù)據(jù),數(shù)據(jù)類型是怎么樣

2,modifiers

2-1 required 不可以增加或刪除的字段,必須初始化

2-2 optional 可選字段,可刪除,可以不初始化

2-3 repeated 可重復(fù)字段, 對應(yīng)到j(luò)ava文件里,生成的是List

3,Message

在proto文件里,數(shù)據(jù)的協(xié)議時以Message的形式表現(xiàn)的。

4, Build

生成具體的java類時,例如Person.java,同時會存在build方法。文檔的意思是對于轉(zhuǎn)化后的數(shù)據(jù),具有唯一性,build提供了便利的方法來初始化這些數(shù)據(jù)。

在AndroidStudio中的配置

1、在project的build.gradle中配置

 buildscript {
    
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
注意:如果gradle的版本是3以下,plugin版本要用0.8.0版本
2、在app的build.gradle中配置
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'

android {
    sourceSets {
        main {
            proto {
                //main目錄新建proto目錄
                srcDir 'src/main/proto'
                include '**/*.proto'
            }
            java {
                srcDir 'src/main/java'
            }
        }
    }
}

//構(gòu)建task
protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.1.0'
    }

    generateProtoTasks {
        all().each { task ->
            task.builtins {
                remove java
            }
            task.builtins {
                java {}
                // Add cpp output without any option.
                // DO NOT omit the braces if you want this builtin to be added.
                cpp {}
            }
        }
    }
    //生成目錄
    generatedFilesBaseDir = "$projectDir/src/generated"
}

dependencies {
    compile 'com.google.protobuf:protobuf-java:3.1.0'
    compile 'com.google.protobuf:protoc:3.1.0'
}

安裝插件(安裝完后重啟)

點(diǎn)擊settings

找到plugins

安裝插件

創(chuàng)建proto文件

創(chuàng)建proto包
package tutorial;

option java_package = "cn.jubo.customsystem";
option java_outer_classname = "AddressBookProtos";

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

message AddressBook {
  repeated Person person = 1;
}
package在Java里面代表這個文件所在的包名,在c#里面代表該文件的命名空間,message代表一個類,
“required”:表示此字段值必填,一個結(jié)構(gòu)良好的message至少有一個flied為“required”
“optional”:表示此字段值為可選的。對于此類型的字段,可以通過default來指定默認(rèn)值,這是一個良好的設(shè)計習(xí)慣。
如果沒有指定默認(rèn)值,在encoding時protobuf將會用一個特殊的默認(rèn)值來替代。對于string,默認(rèn)值為空,bool類型默認(rèn)為false,數(shù)字類型默認(rèn)位0,對于enum則默認(rèn)值為枚舉列表的第一個值。
“repeated”:表示這個字段的值可以允許被重復(fù)多次,如果轉(zhuǎn)換成JAVA代碼,此filed數(shù)據(jù)結(jié)構(gòu)為list,有序的??梢栽凇皉epeated”類型的filed后使用“packed”--壓縮,提高數(shù)據(jù)傳輸?shù)男省?/h6>
特別需要注意:當(dāng)你指定一個filed位required時,需要慎重考慮這個filed是否永遠(yuǎn)都是“必須的”。將一個required調(diào)整為optional,需要同時重新部署數(shù)據(jù)通訊的Client和Server端,否則將會對解析帶來問題。
可以在一個.proto文件中,同時聲明多個message,這樣是允許的。
為message或者filed添加注釋,風(fēng)格和JAVA一樣
optional int32 page = 3;// Which page number do we want? 
數(shù)據(jù)類型與JAVA對應(yīng)關(guān)系
創(chuàng)建完文件后記得執(zhí)行如下操作

創(chuàng)建對象

  AddressBookProtos.Person person = AddressBookProtos.Person.newBuilder()
                .setId(1)
                .setName("text")
                .setEmail("123")
                .build();
        AddressBookProtos.AddressBook book = AddressBookProtos.AddressBook.newBuilder()
                .addPerson(person)
                .build();

性能對比

http://www.sohu.com/a/136487507_505779

感謝以下博客

https://www.cnblogs.com/angrycode/p/6238058.html
http://blog.51cto.com/mikewang/1432136
http://shift-alt-ctrl.iteye.com/blog/2210885

官方文檔

https://developers.google.com/protocol-buffers/docs/proto3

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容