Android UDP传输对象数据的方法(Kotlin)

前言

C++通信传递数据很方便,可以把对象直接打包发送出去,在接收方和发送方都知道其数据格式情况下,就可以很快的传递对象信息。
而Android却不能把类直接打包发送,一开始的时候一直在找能不能直接打包发送,到后面由于时间问题放弃了,中间还尝试ObjectToByte的方法,没弄成。最后落足于把对象的数据转化成Json数据来传输数据了。

这里我只是提供一个思路使用Json传递数据的思路,但就这个思路而言,就能解决所有Android对象的数据传输问题了。

思路

1、如何简单的传递一个对象

这里有一个Tank类

class Tank{
	var x=0
	var y=0
	var dir=100; //横坐标,纵坐标,方向
}
Tank myTank;//初始化一个tank
我们想要发送myTank的数据,但是udp的send()只支持byteArray的数据,
所以需要一种办法,把对象转化成byteArray格式的数据来传输。
这里我们使用使用Json数据格式来做过渡。
1.创建一个JSONObject对象,再通过put(“tag”,data)添加要传输的数据。
val js = JSONObject()
		.put("x",myTank.x)
		.put("y", myTank.y)
		.put("dir", myTank.direction)
2.把JSONObject转换成ByteArray类型,并发送出去。
js.toString().toByteArray()
udp.send(js)//发送的函数肯定不是这样的,udp发送数据(具体方法可以参照我的另外一篇文章《Android简单UDP框架》)
3.接收数据,还原ByteArray为JSONObje对象,并获取数据。
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")
4.但这个过程不免繁琐了一些
所以在这里我们可以做一个简单的优化。
将转换和解析的过程放到对象内部。
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数据生成对象
是不是简单多了,但是我们在项目里往往不只传递这一个数据讯息,
比如在传递对象的时候,我们又要有正常的通信,
这个时候如果要拓展通信范围该怎么做呢。

2、如何进行复杂信息通信

上面传递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数据生成对象
}
以上就是博主关于android传递信息的思路了。
如果有更好的点子希望您能分享一下哦。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值