C++通信传递数据很方便,可以把对象直接打包发送出去,在接收方和发送方都知道其数据格式情况下,就可以很快的传递对象信息。
而Android却不能把类直接打包发送,一开始的时候一直在找能不能直接打包发送,到后面由于时间问题放弃了,中间还尝试ObjectToByte的方法,没弄成。最后落足于把对象的数据转化成Json数据来传输数据了。
这里我只是提供一个思路使用Json传递数据的思路,但就这个思路而言,就能解决所有Android对象的数据传输问题了。
这里有一个Tank类
class Tank{
var x=0
var y=0
var dir=100; //横坐标,纵坐标,方向
}
Tank myTank;//初始化一个tank
我们想要发送myTank的数据,但是udp的send()只支持byteArray的数据,
所以需要一种办法,把对象转化成byteArray格式的数据来传输。
这里我们使用使用Json数据格式来做过渡。
val js = JSONObject()
.put("x",myTank.x)
.put("y", myTank.y)
.put("dir", myTank.direction)
js.toString().toByteArray()
udp.send(js)//发送的函数肯定不是这样的,udp发送数据(具体方法可以参照我的另外一篇文章《Android简单UDP框架》)
val bytes= udp.recv()//接收数据
//这里搓一个函数用于简化代码。
//从Json中用String标签获取Int数据(因为默认取得的是String数据)
fun getIntByStringFromJson(jsonObject: JSONObject, string: String):Int
{
return Integer.parseInt(jsonObject.getString(string))
}
js = JSONObject(String(UDPManager.RecvBuf, 0, UDPManager.RecvBuf.size))//解析ByteArray为JSONObje对象
val x = getIntByStringFromJson(js,"x")//通过之前设置的标签获取数据
val y = getIntByStringFromJson(js,"y")
val direction = getIntByStringFromJson(js,"dir")
所以在这里我们可以做一个简单的优化。
将转换和解析的过程放到对象内部。
class Tank{
var x=0
var y=0
var dir=100; //横坐标,纵坐标,方向
fun toByteArrayByJson():JSONObject{
return JSONObject().put("x",x).put("y", y).put("dir", direction).toString().toByteArray()
}
fun copyByJsonFromByteArray(listenBuf:ByteArray){
val js = JSONObject(String(listenBuf,0,listenBuf.size))
x = getIntByStringFromJson(js,"x")
y = getIntByStringFromJson(js,"y")
direction = getIntByStringFromJson(js,"dir")
updateCenterXY()
}
}
Tank myTank;//初始化一个tank
这样的话原本的流程可以变成
udp.send(myTank.toByteArrayByJson())//发送myTank的数据
val buf = udp.recv() //获取数据
val newTank = Tank().copyByJsonFromByteArray(buf) //copy数据生成对象
是不是简单多了,但是我们在项目里往往不只传递这一个数据讯息,
比如在传递对象的时候,我们又要有正常的通信,
这个时候如果要拓展通信范围该怎么做呢。
上面传递tank信息时,由于知道recv的是tank,直接拿去解析就完事了。
但是如果我们是要传递其他的,比如中断连接的信息,这个时候如果被误作tank信息进行解析,就会产生错误了。
其实我们还是使用json来解决问题。
我们只需要在原来JSONObject生成的时候,多put一个msgType。
然后我们规定,msgType为0的时候就是正常讯息。为1的时候是tank数据。
这样的话我们就可以传递不同的信息了。
依旧是传递tank信息,不过现在构造tank的时候要在后面put(“msgType”,1),为了便于使用,我们改变了Tank原来的内部函数。
fun toJson():JSONObject{
return JSONObject().put("x",x).put("y", y).put("dir", direction)
}
fun copyByJson(js:JSONObject){
x = getIntByStringFromJson(js,"x")
y = getIntByStringFromJson(js,"y")
direction = getIntByStringFromJson(js,"dir")
updateCenterXY()
}
使用的时候变成
//发送断开连接的请求
udp.send(return JSONObject().put("op","断连").put("msgType",0))
//发送myTank的数据
udp.send(myTank.toJson().put("msgType",1))
val buf = udp.recv() //获取数据
val js = JSONObject(String(buf, 0, buf.size))
if(getIntByStringFromJson(js,"msgType")==0)
{
if("断连".compareTo(jsonObject.getString("op"))==1)
{
closeLink()//断开连接
}
}
else if(getIntByStringFromJson(js,"msgType")==1)
{
val newTank = Tank().copyByJsonFromByteArray(buf) //copy数据生成对象
}