记一次全民K歌的crash定位过程(2)

对于线索1,我们先假设是第一种情况,通过追踪FLAG_REMOVED设置的路径,发现只有当业务调用了Adapter的notifyXXXRemoved方法时,才会为ViewHolder添加FLAG_REMOVED标记。而线索二中的Footer实际上是一个容器,业务调用addFooterView添加进来的布局都会填入容器中,不管用户如何操作,对RecyclerView来说,Footer始终是有且只有一个,不存在删除Footer的情况。于是线索一纠正为:从mAttachedScrap中取到的ViewHolder类型与Adapter取到的不一致。

[原文来自:www.11jj.com]

mAttachedScrap中的ViewHolder是通过对比LayoutPosition查找到的,而Adapter.getItemType的结果则是分析数据集而来,两者的不一致说明了RecyclerView的状态与数据集产生了不同步的情况,往往出现在Adapter中的列表数据发生了变化而又没有调用notityXXX方法通知到RecyclerView的情况下。 [原文来自:www.11jj.com]

crash所在的列表并没有请求后台数据却产生了数据的变化,能产生这一现象的只有用户发布作品后,由客户端自己构造的假数据了。

因作品发布与K歌业务逻辑关联较大,参考意义不大,这里只做简要的文字说明:

用户发布作品后,会生成一条发布数据在动态中显示,这条数据是存在于单例中的,两个FeedSubFragment都能取到,发布完成并刷新列表才会把它从单例中清除。另外,用户在K歌内的一些互动操作会触发广播,比如在作品详情页评论了作品,那动态中这个作品的feed评论计数会实时更新,不需要等待列表的刷新操作,广播也都是有..的。

作品刚发布时,不可见的那个页面对此无感知,会出现RecyclerView是Refresh、Header、Footer、Empty、Load五个item的状态,而Adapter的数据集中在Header与Footer间多了一条假feed,虽然没有调用notifyXXX,但当有互动操作或跳其它Activity返回等其它原因触发layout时,也不会引起crash,如下:

记一次全民K歌的crash定位过程(2)

①② 通过position可以从mAttachedScrap正确获取到原来的ViewHolder并直接复用

③ 通过position取到了Footer的ViewHolder,发现类型不同,把它从布局中remove并添加到缓存池RecycledViewPool,最后新创建一个假Feed的ViewHolder

④ 取到了Empty的ViewHolder,同样回收至RecycledViewPool,但因为上一步有把Footer的ViewHolder添加到了RecycledViewPool,处理完Empty后,会尝试从RecycledViewPool查找,而这里是通过viewType来查找的,所以可以找到上一步添加进来的ViewHolder,从而复用

⑤⑥ 同④

当假feed已经被layout出来,数据被删除却没有notify的情况下执行layout又会怎样呢?

记一次全民K歌的crash定位过程(2)

①② 可直接复用

③ 取到了假feed的ViewHolder,回收至RecycledViewPool,然后重新创建了一个Footer的ViewHolder,这就导致了两个ViewHolder指向同一个View的出现,一个新创建的添加到RecyclerView中显示,并清除FLAG_TMP_DETACHED标记,另一个仍然存在于Scrap缓存中未被使用

④ 取到了Scrap缓存中Footer的ViewHolder,尝试回收至RecycledViewPool,却发现Footer已经不是FLAG_TMP_DETACHED的状态,因为上一步已经把它添加到RecyclerView中,清除了这一标记,于是抛出文章开头的IllegalArgumentException异常

可能有人会感兴趣增删数据并调用了notifyXXXRemoved的正常情况下,RecyclerView是如何在preLayout及postLayout阶段都能通过position获取到正确的ViewHolder的,可以自行了解下ViewHolder的mPreLayoutPosition跟mPosition的作用,这里不细说了

五、总结

至此,原因也就比较清晰了:用户使用K歌停留在动态非好友页,退后台被系统杀掉重启时,没有考虑到Fragment恢复的情况,导致在正常的Fragment下多生成了一个不可见的Fragment,之后发布了作品并对其执行了会引起数据变化的互动操作,使其layout到布局中,刷新列表后不可见的RecyclerView列表状态与Adapter数据不同步,跳转到其它Activity再返回时,触发了RecyclerView的重新布局,检测到了状态不对并抛出了异常。

QQ音乐团队诚聘测试、研发。有意者请发送简历至tmezp@tencent.com,请注明来自公众号,我们将优先拜读。

自媒体 微信号:11jj 扫描二维码关注公众号
爱八卦,爱爆料。

小编推荐

  1. 1

    发钱啦!赶快领……

    小编发现支出宝运动又来了,天天都能够领一次红包,并且领取的红包遍及比以前多,有些好几块,好比1元、2元、3元、8元,13元等等。红包领取方

  2. 2

    身体有癌,耳朵先知?提醒:耳朵出现一个症状,或是癌症前兆

    在人体这个周详的机械中,每一个部位都或者是健康状况的“指示器”。有时,一些看似不起眼的症状,却或者是身体内部深条理问题的外在示意。

  3. 3

    2024五一国际劳动节放假通知——中山市精彩童年幼儿园

    2024 龙年大吉点分享点收藏点在看点点赞精彩童年不负韶华GRAGON龙行龘龘 前途朤朤- Happy New Year -打造负责敬业的师资部队;引领合作合营的家长群体

  4. 4

    米色配什么颜色好看图片欣赏(米色配什么颜色好看图片欣赏大全)

    大家好,小丽今天来为大家解答米色配什么颜色好看图片欣赏以下问题,米色配什么颜色好看图片欣赏大全很多人还不知道,现在让我们一起来看看

  5. 5

    怎么提高孩子的注意力(提升孩子注意力的方法)

    大家好,小乐今天来为大家解答怎么提高孩子的注意力以下问题,提升孩子注意力的方法很多人还不知道,现在让我们一起来看看吧!1、保持学习环

  6. 6

    明确了,免票!降价!

    “五一”假期倒计时!江西这些景区免门票、降价等福利大放送快收好这份优惠政策攻略~(信息汇集截止时间2024年4月27日)Part 01.南昌市1.一篇《滕

  7. 7

    厦门社保中心官网登录(厦门社保补缴新政策)

    大家好,小伟今天来为大家解答厦门社保中心官网登录以下问题,厦门社保补缴新政策很多人还不知道,现在让我们一起来看看吧!1、厦门社保查询

  8. 8

    和好友去了趟美容院,忆苦思甜一万年。。。

    异国生活,天天睁眼就是一日三餐。接送孩子的闲暇里洗洗涮涮,晚上再跟时差另一边的团队小伙伴们沟通落成作,时光飞转又一天。社交变得很简

Copyright 2024.依依自媒体,让大家了解更多图文资讯!