前一篇文章Android进阶——性能优化之一种更高效更轻量的序列化方案Protocol Buffer完全攻略(十)总结了Protobuf的一些基础知识以及内部底层的编解码特点和原理,这一篇就好好的总结下Protobuf的应用。以下是性能优化系列的链接地址列表(持续更新):
Android进阶——性能优化之APP启动时黑白屏的根源解析及对应的优化措施小结(一)Android进阶——性能优化之APP启动过程相关源码解析(二)Android进阶——性能优化之APP启动速度优化实战总结(三)Android进阶——性能优化之布局渲染原理和底层机制详解(四)Android进阶——性能优化之布局优化实战经验小结(五)Android进阶——性能优化之内存管理机制和垃圾采集回收机制(六)Android进阶——性能优化之内存泄漏和内存抖动的检测及优化措施总结(七)Android进阶——性能优化之进程提权与保活原理及手段完全解析(八)Android进阶——性能优化之进程提权与拉活原理及手段完全解析(九Android进阶——性能优化之一种更高效更轻量的序列化方案Protocol Buffer完全攻略(十)Android进阶——性能优化之一种更高效更轻量的序列化方案Protocol Buffer完全攻略(十一)一、Protocol Buffer的使用步骤使用Protocol Buffer很简单,无论是任何平台下都是三大步骤:
创建.proto 源文件编译.proto 源文件类似于java文件最终被编译成class 字节码文件,需要依赖于JDK开发环境,Protobuf 也类似需要依赖它自己的编译环境,可以提供的类似SDK包中的protoc.exe把proto文件编译为对应平台下运行的文件,也可以通过IDE插件完成编译,无论何种方式本质上都是一样的,下载protoc-3.8.0-win64 并解压之后就可以通过 protoc -h命令查看帮助,需要对应的指令完成编译,比如说使用protoc --java_out=. xxx.proto编译Java环境下使用的类。
使用编译后的产物中的提供方法二、在AndroID Studio使用ProtobufAndroID Studio使用Protobuf比较便捷,因为AndroID Studio 为我们提供了对应的插件,使得我们只需要去创建.proto源文件就可以了,无需去手动执行编译任务,以下是通用的几大步骤:
1、在AndroID Studio项目中引入protobuf-gradle-plugin Gradle插件在项目根目录下的build.gradle脚本下引入protobuf-gradle-plugin插件
buildscript { repositorIEs { Google() jcenter() } dependencIEs { classpath 'com.androID.tools.build:gradle:3.4.0' //引入protobuf-gradle-plugin Gradle 插件 classpath 'com.Google.protobuf:protobuf-gradle-plugin:0.8.8' }}
2、在需要使用Protobuf 的Module下的build.gradle使用插件并进行对应的配置应用protobuf-gradle-plugin 插件在与androID 节点同级下配置 protobuf节点(这个protobuf节点就是由protobuf-gradle-plugin 插件提供的)引入Google 官方提供的库依赖apply plugin: 'com.androID.application'//应用protobuf插件apply plugin: 'com.Google.protobuf'//配置protobuf插件信息protobuf { protoc { artifact = 'com.Google.protobuf:protoc:3.0.0' } plugins { javalite { artifact = 'com.Google.protobuf:protoc-gen-javalite:3.0.0' } } generateProtoTasks { all().each { task -> task.builtins { remove java } task.plugins { javalite { } } } }}androID{...}dependencIEs { ... implementation 'com.Google.protobuf:protobuf-lite:3.0.0'}
3、创建proto文件经过以上第2、3步骤之后,就可以在项目main主集下新建 proto 目录(即在src/main/目录下创建),再在 proto 目录创建后缀名为.proto的源文件,文件名可以任意取,与.proto文件内部所描述的数据结构无直接联系。
//使用protobuf的版本Syntax = "proto2";//可省package tutorial2;//编译之后生成类所在的包名option java_package = "com.example.tutorial";//编译之后生成类所在的类名option java_outer_classname = "AddressBookProtos";//message 在Java 环境下可以看成是关键字 classmessage Person { //required 表示必须设置值(不能为null),后面的1 并不是赋初始值的作用,是FIEld_Number,编码时会参与到Tag的计算中 required string name = 1; //前面required等 可以看成是注解或者修饰符的作用,紧跟着就是数据类型,然后是变量名 required int32 ID = 2; //optional 表示可选项 optional string email = 3; //枚举类PhoneType在Java环境下会编译为Person的内部枚举类 enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } //类PhoneNumber在Java环境下会编译为Person的内部类 message PhoneNumber { required string number = 1; //设置默认值 optional PhoneType type = 2 [default = HOME]; } //repeated 存储重复的数据 (比如集合) repeated PhoneNumber phones = 4;}message AddressBook { repeated Person people = 1;}
配置环境成功之后并编写完毕,编译项目之后,就会在xx/build/generated/source/proto/deBUG/javalite目录下看到源.proto文件编译后对应的java类:
内部结构对比如下图:
4、使用protobuf 进行序列化和反序列化通过类似构造者模式newBuilder方法来创建对象通过对象调用自带的toByteArray方法实现序列化 *** 作通过对象调用自带的parseFrom方法实现反序列化 *** 作
package com.crazymo.protobuf;import androID.os.Bundle;import androID.support.v7.app.AppCompatActivity;import androID.util.Log;import com.crazymo.protobuf.bean.JsonTest;import com.example.tutorial.AddressBookProtos;import com.Google.protobuf.InvalIDProtocolBufferException;public class MainActivity extends AppCompatActivity { final static String TAG="CrazyMo_"; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); testProtobuf(); } voID testProtobuf() { //通过类似构造者模式来创建对象 AddressBookProtos.Person.PhoneNumber.Builder builder = AddressBookProtos.Person .PhoneNumber.newBuilder().setNumber("666"); AddressBookProtos.Person.Builder person = AddressBookProtos.Person.newBuilder().setname ("CrazyMo") .setID(1).addPhones(builder); AddressBookProtos.Person.PhoneNumber.Builder builder2 = AddressBookProtos.Person .PhoneNumber.newBuilder().setNumber("168"); AddressBookProtos.Person.Builder person2 = AddressBookProtos.Person.newBuilder().setname ("cmo") .setID(2).addPhones(builder2); AddressBookProtos.AddressBook addressBook = AddressBookProtos.AddressBook.newBuilder() .addPeople(person).addPeople(person2).build(); // 序列化 *** 作,将对象转成 byte数组,比如保存为一个文件 long currTime = System.currentTimeMillis(); byte[] bytes = addressBook.toByteArray(); Log.e(TAG, "protobuf 序列化耗时:" + (System.currentTimeMillis() - currTime)); Log.e(TAG, "protobuf 序列化数据大小:" + bytes.length); // 反序列化 *** 作,比如从文件 读到内存 或者 解析从服务器返回的数据 try { currTime = System.currentTimeMillis(); AddressBookProtos.AddressBook addressBook1 = AddressBookProtos.AddressBook.parseFrom (bytes); Log.e(TAG, "protobuf 反序列化耗时:" + (System.currentTimeMillis() - currTime)); } catch (InvalIDProtocolBufferException e) { e.printstacktrace(); } //简单对比下Json的解析 JsonTest.fastJson(); JsonTest.gson(); }}
源码传送门
https://blog.csdn.net/mzpmzk/article/details/80824839
https://www.jianshu.com/p/92dbe1ef0054
https://www.jianshu.com/p/2a5aa5ac6cf6
https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.HTML
https://www.jianshu.com/p/3504d4643dba
https://github.com/protocolbuffers/protobuf
https://github.com/protocolbuffers/protobuf/releases/tag/v3.8.0
https://developers.Google.com/protocol-buffers/docs/downloads
https://developers.Google.com/protocol-buffers/docs/javatutorial
总结以上是内存溢出为你收集整理的Android进阶——性能优化之一种更高效更轻量的序列化方案Protocol Buffer完全攻略(十一)全部内容,希望文章能够帮你解决Android进阶——性能优化之一种更高效更轻量的序列化方案Protocol Buffer完全攻略(十一)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)