BluetoothDevice 序列化问题


前言

在做蓝牙设备通信时,遇到一个奇葩的问题,公司另一个部门开发的蓝牙组件库,把蓝牙设备BluetoothDevice进行了序列化,在连接时候又进行反序列化。但是当我去调试我的项目时,发现发序列化后的对象是个“{}”。


起初,我还纳闷,到底是为什么?为什么?!!!
其他项目组引用时候都没事,怎么到我这里就出问题了?!
难道是我引用组件的姿势不对?


后来对比了下,我发现:把项目的targetSdk降到27就好了!

问题是解决了,但是,为什么呢?

本着不抛弃、不放弃的原则,我去翻看了源码,对比了sdk27和sdk28的BluetoothDevice的源码,结果发现:

除了多了两个方法,其他完全没什么大的区别啊!


这就奇怪了!为什么呢?!!
头皮上的痘痘都挠破了,也想不出来啊!!


思考

冷静下来,认真思考:

问题现象是:BluetoothDevice反序列化后得到的是{},而不是null。说明这个对象还是存在的,只是对象里的属性没有了。

分析

序列化和反序列化都是使用的gson,会不会是gson的bug呢?
于是,我对gson序列化BluetoothDevice的代码,打上断点,一步一步的去排查,最终,在ReflectiveTypeAdapterFactory 中找到了问题的根源。
在这里插入图片描述

原来gson内部也是通过反射获取对象的属性,然后进行一系列的操作,不啦不啦不啦…的

如果序列化后得到的是{},那这里是不是就会有问题。
于是,我通过debug,对比了sdk=27和sdk=28时,raw.getDeclaredFields()这里的区别:


当sdk=27时:
在这里插入图片描述
当sdk=28时:
在这里插入图片描述
震惊了!
sdk=28时,通过反射获取属性,竟然没有找到mAddress,且数组长度比sdk=27是少了好多!

定位

查找了安卓不同api的差异,我终于在安卓9.0中的“行为变更”中发现了端倪:
在这里插入图片描述
对于官方的这块解释,我的理解是:源码中的属性不再是你想通过反射就能自由获取的了!

其实,这个问题在好多功能使用时也遇到过,就是随便从百度搜索的结果中,就能发现之前的有些功能,动不动就是通过反射,调用源码内部的某些私有方法,以达到出奇制胜的效果。在早期的安卓版本中,确实能起到一定的作用,但是随着版本的不断提升,这些方法往往变得调用不通了。

最终,我也是定位到了问题的原因,既然是系统不允许再访问私有属性,那gson自然也拿不到maddress。自然得到的序列化对象没有对应的属性值。

所以,还是改自己的代码吧,别序列化BluetoothDevice了,搞得什么飞机,序列化它干嘛,直接用变量缓存不就完了么!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安静的码字猴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值