Android中protoBuf使用实战,真实和后台交互!

在Android studio中配置使用protobuf,网上有很多资料,但几乎找不到与后台交互,

拿到数据后怎么进行反序列化的操作,下面记录下:

首先定义 .proto文件,我们跟后台交互是有请求头和请求体的。


//这是请求头
message MsgHead {
    fixed32 version = 1; ///< 协议版本号
    fixed32 app = 2; ///< 应用名称
    fixed32 server = 3; ///< 应用内具体业务模块
};


//这是请求体
message MsgBody {
    bytes body = 1; ///< 消息体主体
}



//这是需要发送给服务器的字段。
message radio_category_req {
    uint32 type = 1;
}

//下面3个是服务器返回的数据

//返回的数据集合,包括了错误描述,数据集合列表
message radio_category_rsp {
    errorinfo error = 1; // 错误码信息
    repeated radio_category_info radio = 2; 
}

//通用的描述错误信息
message errorinfo {
    int32 error_code = 1; //错误码
    bytes error_info = 2; //错误描述信息
}


//分类列表
message radio_category_info {
    bytes name = 1; // 分类名字
    uint32 id = 2; // 分类id
}

下面是使用socket进行通讯的类

public class TestProtoActivity extends AppCompatActivity {

    private Socket mSocket;
    private Button btn_send;

    ExecutorService mExecutorService = Executors.newCachedThreadPool();
    private int mHeadLength;
    private byte[] mBytesHead;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_proto);

        //跟后台交互,拿到后台的数据进行反序列化
        btn_send = findViewById(R.id.btn_test_proto);
        

//先创建请求头和请求体
        RadioCategorySend.radio_category_req send = RadioCategorySend.radio_category_req.newBuilder().setType(1).build();
        MsgBodyOuterClass.MsgBody body = MsgBodyOuterClass.MsgBody.newBuilder().setBody(send.toByteString()).build();
        MsgHeadOuterClass.MsgHead head = MsgHeadOuterClass.MsgHead.newBuilder()
                .setVersion(1)
                .setApp(1)
                .setServer(3)
                .setServant(2001)
                .setSeq(1)
                .setRouteId(1)
                .setBodyLen(body.toByteArray().length)
                .build();

        mBytesHead = head.toByteArray();
        byte[] bytesBody = body.toByteArray();

        mHeadLength = mBytesHead.length; //头长度
        /*ZLog.d("-----testProto  mHeadLength:" + mHeadLength);
        ZLog.d("-----testProto  bytesBody:" + Arrays.toString(bytesBody));
        ZLog.d("-----testProto  bytesHead:" + Arrays.toString(mBytesHead));*/

        //我们的请求是头+体,所以需要将2个字节数组进行拼接
        byte[] bytesResult = addBytes(mBytesHead, bytesBody);
        btn_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                send(bytesResult);
            }
        });

    }

    private void testPList() {

    }

    /**
     * 将2个byte数组进行拼接
     */
    public byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;
    }

    private void send(byte[] bytes) {
        mExecutorService.execute(new Runnable() {
            @Override
            public void run() {

                OutputStream os = null;
                InputStream inputStream = null;
                StringBuffer sb = null;
                try {
                    mSocket = new Socket("192.168.189.9", 8080);
                    
                    mSocket.setSoTimeout(1000 * 10);
                    mSocket.setTcpNoDelay(true);
                    os = mSocket.getOutputStream();
                    os.write(bytes);// 把msg信息写入输出流中
                    os.flush();

                    inputStream = mSocket.getInputStream();
                    //由于数据量小,所以就用1024拿一次就够了,优化需要自己优化。
                    byte[] buffer = new byte[1024];    
                    int read = inputStream.read(buffer);
                    //转换为字符串,我这服务器用的编码很奇怪,默认一般使用UFT-8的,可以自己改
                    String tempISO = new String(buffer, 0, read, Charset.forName("ISO-8859-1"));   //ISO-8859-1
                    //最终结果
                    byte[] lastResult = tempISO.getBytes(Charset.forName("ISO-8859-1"));
                    //先解body,这是重点,必须要先把body解出来。用后台返回的字节数据进行解析
                    MsgBodyOuterClass.MsgBody body = MsgBodyOuterClass.MsgBody.parseFrom(lastResult);

                  

                    //这里就能拿到返回的集合列表了##################################
                    RadioCategoryResult.radio_category_rsp cityResult = RadioCategoryResult.radio_category_rsp.parseFrom(body.getBody());
                    ZLog.d("-----testProto  cityResult:" + cityResult.toString());

                    RadioCategoryResult.errorinfo error = cityResult.getError();
                    ZLog.d("-----testProto  error:" + error.toString());
                    List<RadioCategoryResult.radio_category_info> radioList = cityResult.getRadioList();

                    for (int i = 0; i < radioList.size(); i++) {
                        ZLog.d("-----testProto  getName:" + new String(radioList.get(i).getName().toByteArray()) + "---getId:" + radioList.get(i).getId());
                    }

                    mSocket.close();

                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
        });
    }


}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值