前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >protobuf在java, Android下的使用总结

protobuf在java, Android下的使用总结

作者头像
杨永贞
发布2020-08-04 21:26:42
1.7K0
发布2020-08-04 21:26:42
举报

protobuf(Google Protocol Buffers)是Google提供一个具有高效的协议数据交换格式工具库(类似Json),但相比于Json,Protobuf有更高的转化效率,时间效率和空间效率都是JSON的3-5倍。后面将会有简单的demo对于这两种格式的数据转化效率的对比。但这个库目前使用还不是太流行,据说谷歌内部很多产品都有使用。 Protobuf的优点

1,性能好,效率高

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

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

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

可用来做什么?

Protobuf可替代Json,支持Java、C++、Python等语言,简单好用还节省内存流量,可利用Protobuf进行改造,替换原有的Json或者XML存储方式进一步提升性能。还可用在RPC远程过程调用,及客户端、服务器端通信和数据交换。

Xml、Json是目前常用的数据交换格式,它们直接使用字段名称维护序列化后类实例中字段与数据之间的映射关系,一般用字符串的形式保存在序列化后的字节流中。消息和消息的定义相对独立,可读性较好。但序列化后的数据字节很大,序列化和反序列化的时间较长,数据传输效率不高。

Protobuf和Xml、Json序列化的方式不同,采用了二进制字节的序列化方式,用字段索引和字段类型通过算法计算得到字段之前的关系映射,从而达到更高的时间效率和空间效率,特别适合对数据大小和传输速率比较敏感的场合使用。

protobuf转换过的二进制文件具有:

空间效率

Json:107个字节

Protobuf:32个字节

时间效率

Json序列化: 1ms , 反序列化:0ms

Protobuf 序列化: 0ms 反序列化:0ms

将public List<Phone> list和repeated PhoneInfo phoneInfoList =3;都赋值为1000个PhoneInfo

空间效率

Json:4206个字节

Protobuf:1332个字节

时间效率

Json序列化: 4ms , 反序列化:1ms

Protobuf 序列化: 1ms 反序列化:0ms

优点:通过以上的时间效率和空间效率,可以看出protobuf的空间效率是JSON的2-5倍,时间效率要高,对于数据大小敏感,传输效率高的模块可以采用protobuf库。

缺点:消息结构可读性不高,序列化后的字节序列为二进制序列不能简单的分析有效性;目前使用不广泛,只支持java,C++和Python;

使用:

1.首先要在adroid stdio工程根路径下,就是和settings.gradle在同一级目录的build.gradle文件中添加protobuf插件classpath配置。

代码语言:javascript
复制
dependencies {
    classpath 'com.android.tools.build:gradle:3.0.1'
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.2'

2.在app中的build.gradle添加两个protobuf依赖库:protobuf-java和protoc(如图:app模块中添加protobuf依赖库.png)。protobuf-java是用来处理java代码的,protoc是处理C或者C++代码的。

代码语言:javascript
复制
apply plugin: 'com.google.protobuf'
代码语言:javascript
复制
implementation 'com.google.protobuf:protobuf-java:3.1.0'
implementation 'com.google.protobuf:protoc:3.1.0'

3.接着还需要在build.gradle的“android { }”中进行配置自动生成代码的sourceSets目录路径。

代码语言:javascript
复制
sourceSets {
    main {
        java {
            srcDir 'src/main/java'
        }
        proto {
            srcDir 'src/main/proto'
            include '**/*.proto'
        }
    }
}

3-1.自动生成的java资源路径:srcDir 'src/main/java'

3-2. 自动生成的proto资源路径:srcDir 'src/main/proto' 和包括后缀为.proto的文件。

代码语言:javascript
复制
//构建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"
}

4.接下来,在配置的指定位置,即“src/main/”的路径下创建名字为“proto”的文件夹。在“proto”路径下创建.proto为后缀的文件再写上proto格式的代码。

点击“Sync”同步按钮,同步整个工程,protobuf的java代码就会自动生成了,不过生成的是在app/src/genarated文件夹下。使用时

直接import引用过来即可。

举例,一个测试的小demo:

*.proto文件如下:

读写测试demo:

代码语言:javascript
复制
package com.example.yang.myapplication.protobuf;

import  com.yangyongzhen.bean.Testpro;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Testprotobuf {

    public static final String FILE_NAME_READ="testpro.txt";
    public static final String FILE_NAME_WRITE="testpro1.txt";
    public static void main(String[] args) throws IOException {
        System.out.println("protobuf test:");
       //写测试
        Testpro.response.Builder respb = Testpro.response.newBuilder();
        respb.setLedOn(10);
        respb.setNodeId("12345");
        respb.setParentId("67890");
        respb.setUuid("987654321");
        Testpro.response resp = respb.build();
        File file=new File(FILE_NAME_WRITE);
        FileOutputStream outputStream = new FileOutputStream(file);
        resp.writeTo(outputStream);

        //读测试
        File file1=new File(FILE_NAME_READ);
        FileInputStream inputStream = new FileInputStream(file1);
        Testpro.response resp1 = Testpro.response.parseFrom(inputStream);
        int t = resp1.getLedOn();
        System.out.println(t);
        String str = resp1.getNodeId();
        System.out.println(str);
        str = resp1.getParentId();
        System.out.println(str);
        str = resp1.getUuid();
        System.out.println(str);
    }

}

输出结果:

protobuf test: 1 5149013220584027 5149013108519750 121212121

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档