Android Protobuf 初探笔记

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下载



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值