最近开发的项目出现界面莫名其秒的卡住,直到发生ANR
异常退出的问题。
问题排查许久,才发现是由于使用的ViewPager
导致的。
在ViewPager
中使用setCurrentItem
长距离设置当前显示的位置的时候,比如0->600
,600->1000
,1000->500
这样的长距离跳转。会导致函数卡住在
函数中很长时间, 甚至一直不能跳出循环。具体卡住的的循环代码如下:
上述代码中循环体会一直循环到N
结束为止。而这个N
是通过
赋值的。恰好,我们的代码中返回的是Integer.MAX_VALUE
。咨询了同事,当时设置这个数值的目的是为了解决循环滚动展示才设置的。代码是直接抄的 Android无限广告轮播 自定义BannerView / 如何优雅的实现一个可复用的 PagerAdapter。
通过Google搜索关键词 BannerAdapter extends PagerAdapter
可以找到类似的代码。
具体的复现BUG
的例子代码如下:
完整的项目代码可以点击此处下载 ViewPager / ViewPagerAppCompatV7。项目编译完成之后,多点击几次 Change Size
按钮就可以复现界面长时间卡住的情况。第二个项目是支持appcompat-v7:18.0.0
的版本,目的是观察各个版本的代码是否存在不同,结论是,都一样。
这个问题目前的解决方法就是保证ViewPager
中的数据不要太多,比如底层分页显示,每页不要太多。另外就是不要大距离跳转,否则会有很多问题。
如果能把android.support
升级到androidx
的话,可以试试最新的ViewPager2
,最新的ViewPager2
是用RecyclerView
实现的,应该不会有以前的问题了。
这个问题,我已经向Google提交了BUG,估计最后的答复也是要升级到androidx
。