Android开发中集成protobuf协议
2016-01-18 12:29
731 查看
protobuff是Google开源的一个二进制协议,被广泛应用与各大项目中。类似的还有腾讯MIG的JCE,原理上都是通过序号设置成员变量位置,然后实现序列化。但是在集成protobuff到Android中时,由于通过protobuf脚本生成的JAVA文件,含有大量的方法,稍微多生成几个类,就会造成方法方法数超64k。通过在gradle中设置:
可以解决通过生成多个dex文件解决编译问题。但是会造成包变大 and 各种莫名其妙的低版本兼容问题,因此要求是严格控制方法数在64K以内。
所以,在Android集成protobuff时候,不能使用google官方的集成方法,改为使用“Square wire”项目。
项目主页:
https://github.com/square/wire
集成方法:
1、gradle中加入项目组件。
2、加入混淆代码:
3、下载 wire-compiler-VERSION-jar-with-dependencies.jar
wire-compiler-VERSION-jar-with-dependencies.jar是一个编译好的jar包,作用是根据proto语法,生成对应的java文件。
需要注意的是,原项目中并没有给出这个jar包的下载地址,想要下载它,需要去http://search.maven.org/中搜索“com.squareup.wire”。结果链接如下:
http://search.maven.org/#search|ga|1|g%3A%22com.squareup.wire%22
注意下载的jar包版本哦。必须跟gradle中编译的版本保持一致,否则可能会出现编译错误or一些bug。
4、编写proto文件
5、根据proto文件生成java文件。
使用cmd or shell 执行以下命令:
-Dfile.encoding=UTF-8 : 指明生成的java文件编码是utf8,不指明的话,会使用系统编码。在win7系统默认gbk,会出现中文乱码。
--proto_path:proto文件路径,“.”是当前目录。
--java_out : java文件的生成目录。
*.proto:针对所有proto文件生成java文件。
6、使用
java文件已经生成,看代码可以发现,方法数相比protobuf确实减少了很多,同时每个类都会被拆分成单个文件。使用过程中会遇到一些类型转换,例如Message->bytestring or Message->byte 等。仔细看api基本都能满足需要,只有一个Message->bytestring 的转换需要自己实现,详情如下:
android { ....... defaultConfig { ....... multiDexEnabled true } .......
可以解决通过生成多个dex文件解决编译问题。但是会造成包变大 and 各种莫名其妙的低版本兼容问题,因此要求是严格控制方法数在64K以内。
所以,在Android集成protobuff时候,不能使用google官方的集成方法,改为使用“Square wire”项目。
项目主页:
https://github.com/square/wire
集成方法:
1、gradle中加入项目组件。
compile 'com.squareup.wire:wire-runtime:2.0.3'
2、加入混淆代码:
-keep class com.squareup.wire.** { *; } -keep class com.yourcompany.yourgeneratedcode.** { *; }
3、下载 wire-compiler-VERSION-jar-with-dependencies.jar
wire-compiler-VERSION-jar-with-dependencies.jar是一个编译好的jar包,作用是根据proto语法,生成对应的java文件。
需要注意的是,原项目中并没有给出这个jar包的下载地址,想要下载它,需要去http://search.maven.org/中搜索“com.squareup.wire”。结果链接如下:
http://search.maven.org/#search|ga|1|g%3A%22com.squareup.wire%22
注意下载的jar包版本哦。必须跟gradle中编译的版本保持一致,否则可能会出现编译错误or一些bug。
4、编写proto文件
syntax = "proto2"; package squareup.dinosaurs; option java_package = "com.squareup.dinosaurs"; import "squareup/geology/period.proto"; message Dinosaur { // Common name of this dinosaur, like "Stegosaurus". optional string name = 1; // URLs with images of this dinosaur. repeated string picture_urls = 2; optional squareup.geology.Period period = 5; }具体proto语法,请自行搜索。
5、根据proto文件生成java文件。
使用cmd or shell 执行以下命令:
java -jar -Dfile.encoding=UTF-8 wire-compiler-2.0.1-jar-with-dependencies.jar --proto_path=. --java_out=. *.proto需要注意的点:
-Dfile.encoding=UTF-8 : 指明生成的java文件编码是utf8,不指明的话,会使用系统编码。在win7系统默认gbk,会出现中文乱码。
--proto_path:proto文件路径,“.”是当前目录。
--java_out : java文件的生成目录。
*.proto:针对所有proto文件生成java文件。
6、使用
java文件已经生成,看代码可以发现,方法数相比protobuf确实减少了很多,同时每个类都会被拆分成单个文件。使用过程中会遇到一些类型转换,例如Message->bytestring or Message->byte 等。仔细看api基本都能满足需要,只有一个Message->bytestring 的转换需要自己实现,详情如下:
public static ByteString pbToByteString(Message body) { try { Class<? extends Message> aClass = body.getClass(); Field adapter = aClass.getField("ADAPTER"); ProtoAdapter o = (ProtoAdapter) adapter.get(body); return ByteString.of(o.encode(body)); } catch (Exception e) { e.printStackTrace(); } finally { } return null; }
相关文章推荐
- Android ActionBar的基本用法
- Android计算缓存大小并清空缓存
- Android编程实现对文件夹里文件排序的方法
- Android USB通信学习 USB Host设备通信实际应用
- Android Gradle 中的使用maven私有仓库
- android中更改spinner、AutoCompleteTextView切割线的颜色
- Android 自定义弹性ListView控件实例代码(三种方法)
- Android实现数据存储技术
- Android Action Bar 详解篇
- android仿IOS7的两种对话框
- [Android] ImageView.ScaleType设置图解
- Android开发之将两张图片合并为一张图片的方法
- Android一步一步带你实现RecyclerView的拖拽和侧滑删除功能
- Android布局之LinearLayout自定义高亮背景的方法
- Android OTA升级新旧版本任意升级
- android DrawerLayout 侧边栏实现
- Android 手机自动化测试工具有哪几种? (来自知户)
- Android屏幕适配全攻略(最权威的官方适配指导)
- Android Design Support Library——TextInputLayout
- 手把手教你画一个 逼格满满圆形水波纹loadingview Android