当前位置:首页 » 《随便一记》 » 正文

单例持有activity的引用导致list的adpter.notifyDataSetChanged()调用无效,界面不刷新的问题分析。_weixin_41212606的博客

20 人参与  2022年06月05日 09:10  分类 : 《随便一记》  评论

点击全文阅读


一、问题背景

帮助朋友做一个项目中的蓝牙模块,需求是进入功能界面,开启蓝牙连接,离开界面后断开蓝牙连接,已被给后续的模块使用蓝牙资源。

常规逻辑:判断蓝牙权限->扫描蓝牙设备->配对连接->数据传输->关闭蓝牙连接. 每次进入、离开均会连接和断开连接蓝牙。

问题现象:对于同一个蓝牙界面,第一次进入能够显示搜索到的蓝牙设备。当退出后,再次进入不能够显示蓝牙设备,也就无法后续的操作。

二、问题分析

好了,至此,问题的现象和项目中的步骤已经明确。废话不多说先来几段硬核的代码,看看我们的实现主流程。

初始化:涉及到一个搜索的dialog,里面显示搜索到的devices,还有控制蓝牙连接&数据解析的类。

 

 扫描设备:

蓝牙设备的监听通过广播完成(有兴趣的小伙伴可以自行了解蓝牙相关知识,这里只做简单介绍)

资源释放工作:

 

当前我是把蓝牙操作界面所涉及都放在这个基类:BluetoothActivityCompat中。

当我拿到问题时候,简单看了下流程,然后关键点加了一些日志,分别是initview, onStartScan,  onFoundDevice(),了解是否检测到了蓝牙设备,已经管理蓝牙设备的list里面的数据情况。

通过日志分析,生命周期方法正常执行,并且管理蓝牙的集合数据正常,设备可以扫描到蓝牙设备,只是第一次在mSearchingDialog中显示了已经扫描到的蓝牙设备,后续扫描到的设备不显示,至此问题定性完成:UI显示没有及时更新导致,蓝牙功能正常。

发现了问题的根因,接下来修改:首先

我们可以看到原先的思路是,调用mBluetoothAdapter.notifyDataSetChanged()对数据进行操作,因为涉及到多出的数据清除,添加。所以我修改了数据刷新的方式,并将adpter初始化中的数据源修改

 adapter中添加setData()方法当运行后惊喜的发现,依然不行。之后是网上百度环节,百度给出的场景多为:adapter中的数据源被修改了地址的指针,姑且称作数据源为mData, 一般为mData = list;修改了mData的内存地址,然而adapter中的数据依然指向原有的数据集地址,好似黑夜中看到了一丝丝的火光,恨不得立马燃爆我的内心。马上开箱去检查我的代码。

然后做出修改:

这样子好像大功告成,刷新了数据并且避免了数据源指向新的对象, 堪称完美。但是打脸的时刻在下一秒来临,一顿 running,依旧如故。至此我陷入了无穷的思考,然后把思绪迁移到对象的释放上来,会不会是由于dialog没有销毁,或者是adapter没有销毁导致的呢?然后在destroy中添加了释放的代码,并且在initview中添加了对象的日志打印;

 

经过日志分析后发现并无异样,正常的释放和初始化,并且开始adapter=null,这一切看似都没有问题。那么我怀疑是不是这个activity的启动模式是singletask/singletop呢,导致了重新进去并没有销毁把之前的界面展示出来。赶紧查看mainifest.xml啥也没发现,一看是默认的standard。在我后续的测试中发现了,多测试几次出现了crash,原因是mBlueetoothAdapter不能为null,一看代码,映射到onStartScan() 中

 按照常规分析,此activity是standard模式,生命周期中执行了onDestroy(),应该每次进入都会产生一个新的实例,对应java的内存栈的话,应该是隔离的,这里的crash是在initview()执行后,按照道理不会产生crash,日志为证:

 如果说crash 的话只有一个原因,activity的实例依然存在java内存中, 我并没有进行内存分析,先按照我的思路寻找内存泄露的点。一顿查阅代码后发现,此activity中引用了一个单例的蓝牙管理类

 确实通过listener的方式持有了activity的引用,导致释放不掉,再次进入也就会产生操作的还是上一个activity 的对象的问题,就会出现进入展示了一个新的dialog,但是没有展示数据,因为那些对象全都是上一个的。

修改方案:每一个都是standard模式,没有必要单例,所以改成非单例模式。也可以通过WeakReference来完成优化。此处我选择第一种。至此问题解决,再次运行完美通过。

三、总结

1.遇到问题需要先找到根因,再指定解决方案,不能急躁,不然越着急越是搞不定。

2.adapter 刷新数据失效的原因,数据源变为新的对象,指向新的地址。 至于有助于理解java内存中的对象的引用机制。

3.内存泄露的现象,分析机制,已经如何解决。即使之前我可能看过很多博客,但是没有亲自遇到修改相关问题,理解更加深入了一步。

好了,今天周五,祝愿各位看官每天都能像周五一样迎接周末。


点击全文阅读


本文链接:http://www.zhangshiyu.com/post/41407.html

蓝牙  数据  设备  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 再别青山,不见桃花新上_云舒燕安禹侯府常读_小说后续在线阅读_无删减免费完结_
  • 重生到被换命格前,薄情未婚夫我不要了全新_沈云淮方梦薇梦薇好评_小说后续在线阅读_无删减免费完结_
  • 前尘誓骨空成碑正版(陆彦轩楚静瑶)_前尘誓骨空成碑正版(陆彦轩楚静瑶)
  • 战霆骁姜绾::结局+番外评价五颗星-重生被读心后,高冷战爷跪地哄:结局+番外新上热文
  • 只为自己(乔芝芝池鑫翊)全书浏览_只为自己全书浏览
  • 被纨绔世子抽签选为未婚妻,截瘫竹马悔疯了完整文本_周明周母叶行舟精修版_小说后续在线阅读_无删减免费完结_
  • 堂妹高考700分,却成了家族笑话一口气完结_二叔魏芯悦大伯母在线阅读_小说后续在线阅读_无删减免费完结_
  • 终章小说封承尧苏琼语完结篇(苏琼语封承尧)已更新+延伸(封承尧苏琼语)清爽版
  • 靳怀琛苏芋冉附加完整在线阅读(苏芋冉靳怀琛)最近更新列表
  • 全书浏览终是庄周梦了蝶完结+番外(南语沈聿珩)_终是庄周梦了蝶完结+番外(南语沈聿珩)全书结局
  • 开挂辅助成团宠,全星际争当大冤种!番外+结局(白希薇沈星河),开挂辅助成团宠,全星际争当大冤种!番外+结局
  • 观风亦止遇惊鸿高分完本(许嘉柔陆砚)全书免费_(许嘉柔陆砚)观风亦止遇惊鸿高分完本后续(许嘉柔陆砚)

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1