美文网首页程序员
在AndroidStudio中搭建Protobuf

在AndroidStudio中搭建Protobuf

作者: Master_文 | 来源:发表于2018-01-03 13:46 被阅读0次

    什么是Protobuf

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

    Protobuf的优点

    1,性能好,效率高

    2,代码生成机制,数据解析类自动生成

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

    4,支持多种编程语言(java,c++,python)

    5,参考文档:http://blog.csdn.net/caisini_vc/article/details/5599468

    Protobuf的缺点

    1, 应用不够广

    2, 二进制格式导致可读性差(二进制格式)

    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文件

    相当于确定数据协议,数据结构中存在哪些数据,数据类型是怎么样

    2,modifiers

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

    2-2 optional 可选字段,可删除,可以不初始化

    2-3 repeated 可重复字段, 对应到java文件里,生成的是List

    3,Message

    在proto文件里,数据的协议时以Message的形式表现的。

    4, Build

    生成具体的java类时,例如Person.java,同时会存在build方法。文档的意思是对于转化后的数据,具有唯一性,build提供了便利的方法来初始化这些数据。

    在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'
                }
            }
        }
    }
    
    //构建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'
    }
    

    安装插件(安装完后重启)

    点击settings
    找到plugins
    安装插件

    创建proto文件

    创建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”:表示此字段值必填,一个结构良好的message至少有一个flied为“required”
    “optional”:表示此字段值为可选的。对于此类型的字段,可以通过default来指定默认值,这是一个良好的设计习惯。
    如果没有指定默认值,在encoding时protobuf将会用一个特殊的默认值来替代。对于string,默认值为空,bool类型默认为false,数字类型默认位0,对于enum则默认值为枚举列表的第一个值。
    “repeated”:表示这个字段的值可以允许被重复多次,如果转换成JAVA代码,此filed数据结构为list,有序的。可以在“repeated”类型的filed后使用“packed”--压缩,提高数据传输的效率。
    特别需要注意:当你指定一个filed位required时,需要慎重考虑这个filed是否永远都是“必须的”。将一个required调整为optional,需要同时重新部署数据通讯的Client和Server端,否则将会对解析带来问题。
    可以在一个.proto文件中,同时声明多个message,这样是允许的。
    为message或者filed添加注释,风格和JAVA一样
    optional int32 page = 3;// Which page number do we want? 
    
    数据类型与JAVA对应关系
    创建完文件后记得执行如下操作

    创建对象

      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

    相关文章

      网友评论

        本文标题:在AndroidStudio中搭建Protobuf

        本文链接:https://www.haomeiwen.com/subject/eydhnxtx.html