美文网首页Android
在Android中使用Protocol Buffers 与测试用

在Android中使用Protocol Buffers 与测试用

作者: 牵手生活 | 来源:发表于2020-04-05 17:43 被阅读0次

    参考资料

    ProtocolBuffer在Android端的解析
    Android Studio使用ProtocolBuffers
    在Android中使用Protocol Buffers
    Android Protobuf应用及原理-饿了么团队
    Protobuf不管在时间和空间上更高效,是怎么做到的呢?

    消息经过Protobuf序列化后会成为一个二进制数据流,通过Key-Value组成方式写入到二进制数据流,如图所示:


    messge Buffer

    安装protobuf-gradle-plugin

    protobuf support插件

    下载编译Protocol编译器

    #支持不同语言,Android选择java即可-protobuf-java-3.11.4.zip(需要gcc 和make编译环境)
    #后来改为protoc-3.11.4-win64.zip(已经是编译好的,无需再编译)
    
    
    https://github.com/google/protobuf/releases
    

    进入protobuf目录并执行 autogen.sh--->这个脚本主要用于下载测试用的gmock-1.7.0,并生成用于编译配置的 configure 等文件。
    不过我注意到目前下载的已经包括了configure文件


    image.png

    configure 等文件。可以通过如下命令了解我们可以对protobuf的编译做哪些配置,以及默认配置的信息:


    image.png

    执行configure对编译进行配置:


    configure对编译进行配置 image.png

    很可惜的是windows上好像没有对应的make命令,对其进行编译。只好到网络上找一个现成的

    #查看版本
    protoc3.0.0  --version
    #查看帮助
    protoc3.0.0  -help
    

    image.png

    创建 .proto 文件

    .proto 文件中的定义很简单:为每个想要序列化的数据结构添加一个 消息(message) ,然后为消息中的每个字段指定一个名字和类型以及一个tag数字。如官方提供的一个例子addressbook.proto:

    addressbook.proto(这里指定了proto的版本,因为proto3.0中已经不支持默认值)

    syntax = "proto2";
    package protoBuffer;
    
    option java_package = "younghare.com.protoBuffer";
    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;
    }
    
    image.png

    编译.proto文件

     protoc --java_out=D:/ test.proto Javaout
    #后面的是编译输出的路劲地址,第二个參数是须要编译的proto文件
    protoc3.0.0 --java_out=D:/  ./addressBook.proto
    
    image.png

    生成的位置是--java_out指定的位置加proto中配置的包名
    如本例子就是d:\younghare.com.protoBuffer

    把生成的代码copy到工程

    image.png image.png

    导入依赖

    implementation 'com.google.protobuf:protobuf-lite:3.0.0' //依赖protobuf-lite库  奇怪的是还要类找不到can not resolve symbol com.google.protobuf.ExtensionRegistry
    #实在没办法,从其他地方copy protobuf的源码到工程
    
    protobuf的源码copy

    编写测试用例

       
        //测试用:系列化与反序列化
        @Test
        public void testAddressBookWriteFile(){
            String pbfilepath = "D:\\temp\\addressBookProtos";
    
            File fproto = new File(pbfilepath);
            if (!fproto.exists()) {
                try {
                    fproto.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            //构造builder
            AddressBookProtos.AddressBook.Builder addressBookBuild = AddressBookProtos.AddressBook.newBuilder();
            AddressBookProtos.Person.Builder personBuild = AddressBookProtos.Person.newBuilder();
    
            AddressBookProtos.Person.PhoneNumber.Builder personPhoneNumberBuild = AddressBookProtos.Person.PhoneNumber.newBuilder();
    
    
            personPhoneNumberBuild.setNumber("138-9999-8888");
            personPhoneNumberBuild.setType(AddressBookProtos.Person.PhoneType.HOME);
            //填充数据
            personBuild.setEmail("young@qq.com");
            personBuild.setName("young cai");
            personBuild.setId(1);
            //addressBookBuild.setPerson(1,personBuild);
    
            //结束 build
    
            AddressBookProtos.Person person = personBuild.build();
    
    //写文件
            try {
                FileOutputStream foProto = new FileOutputStream(fproto);
                person.writeTo(foProto);
                foProto.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            //模拟模拟重文件中反序列化回来
            byte[] buffer = personBuild.build().toByteArray();
    
            try {
                AddressBookProtos.Person person2 = AddressBookProtos.Person.parseFrom(buffer);
                System.out.println(person2.getEmail());
            } catch (InvalidProtocolBufferException e) {
                e.printStackTrace();
            }
    
            String strBase64Value = new String(Base64.encodeBase64(buffer));
    
    
            System.out.println(strBase64Value);
    
    
        }
    
    
    
    

    允许效果

    保存文件 反序列化

    相关文章

      网友评论

        本文标题:在Android中使用Protocol Buffers 与测试用

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