美文网首页
记录 protobuf gradle plugin 生成 序列化

记录 protobuf gradle plugin 生成 序列化

作者: RenHaiRenWjc | 来源:发表于2019-07-27 09:10 被阅读0次

    众所周知,xml 和 json 常见的、应用广泛的序列化和反序列化协议,而 google 自家出产的 Protobuf 也是具备了优秀协议所需要的众多典型特征。

    • 标准的 IDL 和 IDL编译器,这使得对工程师非常友好
    • 序列化数据非常简洁,与 xml 相比,其序列化后的数据大小约 xml 的1/3到1/10
    • 解析速度非常快,对比 xml,是其的20-100倍
    • 提供了友好的动态库,使用简单,反序列化只需要一行代码

    那在 android 如何简单快捷地使用 protobuf 呢

    android 提供了一个插件 protobuf gradle plugin,在构建时生成序列化文件

    • 根目录 build.gradle 配置 protobuf gradle plugin
    buildscript {
        
        repositories {
            google()
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.0.0'
            classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.8'
    
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    
    • 项目 build.gradle 配置 protobuf
    apply plugin: 'com.google.protobuf'  //声明插件
    . . .
    android {
        . . .
        sourceSets {
            main {
                java {
                    srcDir 'src/main/java'
                }
                proto {
                    srcDir 'src/main/protoBean'  // proto 文件位置
                }
            }
        }
    
    }
    protobuf {  //配置 proto 编译器
        protoc {
            artifact = 'com.google.protobuf:protoc:3.5.1'  //注意 这里版本号需要与 protobuf-java lib 一致
        }
        //这里配置生成目录,编译后会在 build\generated\source\proto 的目录下生成对应的java文件
        generateProtoTasks {
            all().each { task ->
                task.builtins {
                    remove java
                }
                task.builtins {
                    java {}
                }
            }
        }
    }
    dependencies{
           . . .
         implementation 'com.google.protobuf:protobuf-java:3.5.1' //依赖 protobuf-java lib
    }
    
    • proto 文件,即需要序列化的文件
    syntax = "proto3";
    
    option java_package = "com.wjc.jcdemolist.demo.protoBuf";
    option java_outer_classname = "_StudentSerializable";
    
    message _Student {
        //指定字段的类型 定义字段的编号,在Protocol Buffers中,字段的编号非常重要
        // 字段名仅仅是作为参考和生成代码用。需要注意的是字段的编号区间范围,
        //其中19000 ~ 19999被Protocol Buffers作为保留字段
        string name = 1;
        string sax = 2;
        int32 age = 3;
        //required指定该字段必须赋值,禁止为空(在v3中该约束被移除);optional指定字段为可选字段,可以为空,
        //对于optional字段还可以使用[default]指定默认值,如果没有指定,则会使用字段类型的默认值
        repeated _Course course = 4; //使用repeated指定字段为集合
    
    }
    //在一个proto文件中可以同时定义多个message类型,生成代码时根据生成代码的目标语言不同,
    //处理的方式不太一样,如Java会针对每个message类型生成一个.java文件
    message _Course {
        string name = 1;
        float score = 2;
    }
    
    

    proto 语法这里就不说讲啦,如需要详情了解,自个百度吧
    注意在项目 build.gradle 中,需要把这个文件路径放入配置中

    • 生成 protobuf.java 代码
      android studio 下 Build -> Rebuild Project 后,在 build \ generated \ source \ proto 会生成对应 protobuf java 代码

    生了 protobuf java ,那如何用呢,请看下面

    public static byte[] serialize() {
        _StudentSerializable._Course.Builder courseBuilder = _StudentSerializable._Course.newBuilder()
                .setName("中文").setScore(149);
        _StudentSerializable._Student.Builder studentBuilder = _StudentSerializable._Student.newBuilder();
        studentBuilder.setName("Jc").setAge(16).setSax("man").addCourse(courseBuilder);
        _StudentSerializable._Student student = studentBuilder.build();
        return student.toByteArray();
    }
    
    public static _StudentSerializable._Student deserialize(byte[] bs) {
        try {
            return _StudentSerializable._Student.parseFrom(bs);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    

    使用起来,是很简单吧,序列化使用 builder 模式,而反序列化一行代码就行了


    相关文章

      网友评论

          本文标题:记录 protobuf gradle plugin 生成 序列化

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