您的位置:首页 > 移动开发 > Android开发

Android Protobuf 初探笔记

2014-04-16 10:15 525 查看

Android Protobuf初探笔记

因项目需要,研究了下Protobuf (Protocol Buffers)在android上简单使用。项目背景类似于qq手机端聊天功能。

解决问题:android客户端与服务器间通信,消息传递。

domo下载

protobuf java 打包jar文件(打包jar可以忽略,可以直接用demo里jar)

1、下载 Protobuf 源码和编译器,我下载的是protoc-2.5.0-win32.zip、protobuf-2.5.0.zip,注意源码和编译器版本一致。

2、安装并配置好maven,可参考博文

3、cmd进入解压好的源码java的目录,执行 mvn package ,跑了挺长时间之后报错,找不到 protoc 。

把下载的 protoc-2.5.0-win32.zip 里的 protoc.exe 放到 源码java/src目录,继续 mvn package,还是找不到 protoc 。

打开 java/pom.xml

约81行和99行的<exec executable="../src/protoc"> 修改为 <exec executable="./src/protoc"> 保存。

继续mvn package,这次成功了。源码/java/target 目录 会生成 protobuf-java-2.5.0.jar。

使用

4、接下来新建一个android的项目(我的项目名称为TestPb)。protobuf-java-2.5.0.jar 复制到 libs目录下。

5、TestPb根目录新建文件夹 proto。

6、接下来需要在proto文件夹写 proto文件,这里我定义为 Msg.proto 内容如下

package com.x.pb.proto;

option java_package = "com.x.pb.proto";
option java_outer_classname = "MsgProbuf";

message Msg  {
required MsgHead  msghead = 1;
required string msgbody = 2;

message MsgHead {
required string command = 1;
required string extras = 2;
}
}
可以理解为定义一个Msg类,Msg类里包含 内部类 MsgHead。 Msg类里有两个成员变量,MsgHead类型的 msghead,以及 string类型的 msgbody。

package(命名空间,防止项目冲突)将会解析为java的包,除非另外指定java_package。

java_outer_classname 为将来生成的java文件名称。在此处了解更多。

7、复制 protoc.exe 到proto文件夹,cmd进入 proto文件夹 然后键入

protoc --java_out ../src *.proto


java类文件会自动生成出来,刷新下工程,看到结构大致如下:



接下来开始写代码了。我的代码主要实现主界面一个按钮,点击按钮,把生成Msg对象并发送到服务器(利用scoket)。

android端代码:

class SendTask extends AsyncTask<Void, Integer, String>{

@Override
protected String doInBackground(Void... params) {

Msg.MsgHead.Builder msgHeadBuilder = Msg.MsgHead.newBuilder();
msgHeadBuilder.setCommand("test");
msgHeadBuilder.setExtras("中文行不行");
MsgHead msgHead = msgHeadBuilder.build();

Msg.Builder msgBuilder = Msg.newBuilder();
msgBuilder.setMsghead(msgHead);
msgBuilder.setMsgbody("哈哈");
Msg msg = msgBuilder.build();
Socket socket = null;
try {
socket = new Socket("192.168.191.1", 9991);
msg.writeTo(socket.getOutputStream());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
}
}
}
return "";
}

}


服务端代码:
注意需要把刚才生成的MsgProbuf.java复制到服务器端,当然也可以复制proto文件,然后再服务器重新生成。

public class SocketManager {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) {
SocketManager manager = new SocketManager();
manager.doListen();
}

public void doListen() {
ServerSocket server;
try {
server = new ServerSocket(9991);
while (true) {
Socket client = server.accept();
new Thread(new SSocket(client)).start();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("端口绑定错误");
}

}

// 服务器进程
class SSocket implements Runnable {

Socket client;

public SSocket(Socket client) {
this.client = client;
}

public void run() {
DataInputStream input;
DataOutputStream output;
try {
input = new DataInputStream(client.getInputStream());
output = new DataOutputStream(client.getOutputStream());
//
byte len[] = new byte[1024];
int count = input.read(len);
byte[] temp = new byte[count];
for (int i = 0; i < count; i++) {
temp[i] = len[i];
}
Msg msg = Msg.parseFrom(temp);
MsgHead msgHead = msg.getMsghead();
System.out.println("msghead: command=" +msgHead.getCommand() +"  extras="+msgHead.getExtras());
System.out.println("msgbody: " +msg.getMsgbody() );
} catch (IOException e) {
e.printStackTrace();
}
}
}

}


运行效果:



domo下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: