-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【BUG反馈】 #218
Comments
没理解你的意思,根据错误日志是没有在主线程执行。 |
我重新整理一下语言,log 报的是你的库中在使用ListView的时候的问题,可以这样复现,我将 menuList 传入到 PopMenu 中,然后我在外部将 menuList 进行了修改,在这时,就会发生闪退,因为对于 ListView 来讲,数据发生了变化,但又没有进行 notifyDataSetChanged,这时数据和 UI 就对不上了,然后发生的闪退,所以库中 PopMenu 应将我传入的 menuList 进行addAll 到库中自己的 List 当中,这样就可以避免这样的闪退。 |
不知道这次我有没有描述清楚。 |
是使用 |
不是,是使用 PopMenu.show(view, items) ,随后我对 items 进行了修改。对于我的代码来讲,items 是共用的,而且是会变化的。 |
不过 setMenuList 也应该把传入进来的 menuList 进行 addAll 到 PopMenu 中的 menuList。 |
是需要在 |
不是,是我在改了要传入的 menuList 的时候,会闪退。 |
因为随后我对传入的 menuList 进行了修改。对于我的代码来讲,menuList 是共用的,而且是会变化的。 |
很抱歉我这边未能在Demo中复现,目前版本Demo的表现是 |
我再换一种描述方式,对于 ListView 来讲,传入 ListView 的 List 数据是可以修改的,不过如果修改了数据,必须要进行 notifyDataSetChanged,不然就会出现数据和 UI 对不上的情况,就会导致闪退。 PopMenu 使用了 ListView,对于现在的 PopMenu 来讲传入的 List 是不可以修改,不然就会造成我刚才讲的闪退,但是我现在的需求是外面的 List 是可变的,我需要修改他,在下次 show PopMenu 的时候,列表的数据是需要不一样的,所以内部不应该直接使用我传入的 List ,也就是不要用赋值的操作,而应该 new 一个 List 然后使用 addAll 的方式。 |
很抱歉未能复现此错误,上述代码在最新版本的Demo中执行正常,没有发生崩溃 |
复现很容易,我给你写段伪代码,刚才写的代码不够全面。 List<CharSequence> items = new ArrayList();
items.add("选项1");
items.add("选项2");
items.add("选项3");
PopMenu.show(view, items);
//会造成闪退的代码
new Thread(new Runable{
for(int i = 0; i < 10000; i++) {
items.clear();
items.add("选项4");
}
}).start() |
原因我刚才描述错了,重新梳理一下,就是当 ListView 在使用传入的 List 的时候,同时数据也在发生变化,这样就会造成闪退,因为 ListView 拿数据的时候会有点晕。 |
发现问题,在 thread 中加入 sleep 后发生 crash |
稍等正在排查 |
我这边不需要 sleep,你加上循环久一些,可能是时间不够久。这个时机就是 ListView 正在使用 List 数据的时候,刚好 List 也在发生变化,产生的闪退,所以只需要不直接使用我传入的 List 数据,而是在 PopMenu 里复制一份自己用的,就好了,不要使用同一个 List 对象。 |
这个应该是ListView本身的问题。目前我的解决方案是在 ListView 中重写:
其表现为,当数据发生变化后只要触发此问题,会强制刷新列表后继续执行。 |
我认为 try catch 不是好的解决方式,而是去防止数据随意发生变化,比如我一直有在提到的解决方案。 |
但也存在在 PopMenu 运行中需要对菜单进行修改的需求,此时若对于 menuList 直接进行 newArray 可能造成 adapter 无法关联并刷新菜单的问题,我正在思考合理的解决方案。 |
不会的,只要在修改menuList 的时候,同时进行 notifyDataSetChanged 就不会出现这种情况。刚才的闪退是因为在子线程进行了数据更新,如果是在主线程也不会闪退。 |
做不到,原因是 DialogX 必须等待主线程执行 |
大佬,你听我的试一下,保证不会闪退,我打包票。 |
我说了,得考虑存在在 PopMenu 运行中需要对菜单进行修改的需求,此时若对于 menuList 直接进行 newArray 可能造成 adapter 无法关联并刷新菜单的问题,我正在思考合理的解决方案。 |
这种情况下只按照你的想法去处理会导致菜单无法刷新 |
预期的合理方案为: |
如果你还会担心有人在使用的时候在子线程进行 setMenuList 的话,你可以在 setMenuList 上加上注解 @mainthread ,这样也能避免问题。 |
DialogX 必须尽可能的自己考虑线程,而不是要求用户去处理线程问题。 |
按照上述预期的合理方案,既能满足你的想法,也能兼顾需要更新菜单内容的用户。 |
那你可以自己去 post 到主线程呀,而且你本身如果传入的是 CharSequence[] 类型,你就是会去 new 一个呀,所以有什么区别呢? |
对啊,请仔细阅读我刚刚发的预期的合理方案 |
我没否认你的修改建议,但我必须兼顾需要更新菜单内容的用户,这两者并不冲突 |
大佬,你再认真看一下出现的原因,不是因为我使用了 setMenuList,而是我在外部对 menuList 进行了修改,因为我外面用的 list 和 PopMenu 里的 menuList 是同一个数据,对象是传值,List是传址,你所讲的方案,并没有解决我在外问修改 list 的问题呀,我修改的只是 list ,但是我并不想要现在已经展示给用户的 PopMenu 上的 item 发生改变。只是在下次使用的时候改变。 |
而我所说的解决方案,很简单,并不需要影响到老用户。只需要 public PopMenu setMenuList(List menuList) 里和 public PopMenu setMenuList(String[] menuList) 一样,都是 new ArrayList<>() ,然后再 addAll() ,就解决了。 |
是这样的啊 |
了解了,要不这样,你更新一版,我看一下代码得了。可能在这交流不是很好描述。 |
我懂了,你只是将 notifyDataSetChanged 的时机改到了其它地方,了解了。 |
更新好新的一版请发我哦,谢谢了,我这边今天需要发版,感谢。 |
大佬之前是写 c/c++ 的吗?经常用指针这样的词,其实不是指针发生变化,是数据发生变化 。 |
请更新至 0.0.45.beta24 版本,更新日志在:https://github.com/kongzue/DialogX/releases/tag/0.0.45.beta24 |
好的,谢谢了,已更新。 |
是指针没有发生变化, adapter里还是指向了你 new 的array,而array发生了变化,但listview依然按照指针去找之前的 list 拿数据就崩掉了 |
新版本已经处理了,全部会在设置 list 的时候转移到一个新的 list 拷贝,这样不会出现问题了 |
大佬请确认一下aar包没问题,我这边看aar包中的代码没有更新,是不是upload失败了。 |
提交日志在这里:8103602 |
一共还有3处使用的 this.menuList = menuList; |
好的,稍等 |
麻烦了。 |
我这边刚刚调试没有用 view参数 |
请更换 0.0.45.beta25 版本,已修复全部问题。 |
赞 |
BUG 反馈 PopMenu 在线程中修改数据导致闪退
问题描述:
在使用 PopMenu 进行展示时,我可能会随时修改传入的 menuList,所以在 PopMenu 进行初始化的时候,应该是将 menuList 进行一次重新的add添加,否则当我在外部修改 menuList 的时候,就会发生闪退,闪退的日志如下:
希望可以尽快修复一下,感谢。
The text was updated successfully, but these errors were encountered: