一、protobuf文件编写
proto文件编写也是要遵从解耦的,java中class关键字用message代替,在message中声明成员变量。同时,也要定义入口message:(以下入口为ParkFeedback,入口为自定义,包裹其他message的最外层message )
syntax = "proto3";
import "Base.proto";
option objc_class_prefix = "FF";//objc前缀
message ParkFB {
enum GStatus {
G_STATE_UNKNOWN = 0; // 未知
G_STATE_OUT = 1; // 放开状态
}
enum ChargingStatus {
CHARGING_STATE_NOT = 0; // 未充电
CHARGING_STATE_INIT = 1; // 充电初始化
CHARGING_STATE_POWER_OFF = 2; // 充电初始化
CHARGING_STATE_POWER_ON = 3; // 开机充电
CHARGING_STATE_COMPLETED = 4; // 充电完成
}
bool initState = 1; // 初始化状态
bool infraredState = 2; // 红外状态
int32 chargingState = 3; // 充电状态
}
message ParkFeedback {
ParkFB park = 1; // 设备
}
关于规则,先声明enum,后声明变量。enum从0开始定义,变量从1开始定义,否则编译报错。
通讯交互都是互相的,以上例子为从设备回调,主设备控制例子如下:
syntax = "proto3";
enum ActionState {
ACTION_STATE_UNKNOWN = 0;
ACTION_STATE_FINISH = 1; // 正常完成
ACTION_STATE_ERROR = 2; // 错误未完成
}
// :100
message CAction{
message Request{
enum ActionType{
OPEN = 0;
CLOSE = 1;
}
ActionType action_type = 1;
}
message Feedback{
}
Request request = 1;
Feedback feedback = 2;
}
// 开启充电: 101
message ChargingOnAction{
message Request{
}
message Feedback{
}
Request request = 1;
Feedback feedback = 2;
}
// 停止充电: 102
message ChargingOffAction{
message Request{
}
message Feedback{
}
Request request = 1;
Feedback feedback = 2;
}
// 测试例子 : 103
message DemoAction{
message Request{
bool isClose = 1; // 是否关闭,默认true关闭,false不关
}
message Feedback{
ActionState state = 1;
}
Request request = 1;
Feedback feedback = 2;
}
message ControlFeedback
{
int32 compid = 1; // 组件ID
int32 msgId = 2; // 消息ID
int32 errCode = 3; // 错误码, 10000 代表没有错误
string errMsg = 4; // 错误消息
bytes data = 5; // 由组件 ID 与消息 ID 共同确定字段类型
}
就是综合的各种message、enum、变量等的融合。
二、Android Studio自动生成java文件
在项目gradle的dependencies中添加:
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.9'
app的gradle引入第三方库:
implementation 'com.google.protobuf:protobuf-lite:3.0.1'
同时在最上面android plugin下面声明:apply plugin: 'com.google.protobuf'
添加protobuf代码块:
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.5.1-1'
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite {}
}
}
}
}
proto文件放在/java/proto文件夹下:
参考部分文章要求配置路径,我没配置也生成了,配置路径如下:
sourceSets {
main {
java {
srcDir 'src/main/java'
}
proto {
srcDir 'src/main/proto'
}
}
}
配置完成之后,点击build会根据proto文件自动生成.java文件。
在app/build/generated/source/proto/下,可能在xxxDebug下目录里面。
将该.java文件从build文件夹取出,按您习惯放置在/java文件夹下即可正常调用。
三、实际交互使用
承接上述例子,使用的话在解析的位置直接用就行:
SandARemoteCtlData.Control control = SandARemoteCtlData.Control.parseFrom(message); SandARemoteCtlData.ControlFeedback.Builder feedback = SandARemoteCtlDataControlFeedback.newBuilder();
feedback.setXXX...
SandARemoteCtlData.Action action = SandARemoteCtlData.Action.parseFrom(control.getCustomData());
SandARemoteCtlData.Action.Request.ActionType actionType = action.getRequest().getActionType();
switch (actionType) {
case OPEN:
break;
case CLOSE:
break;
}