关于ViewPager设置属性页setCurrentItem会阻塞主线程ANR总结
关于android开发设置View Pager的直接跳转页set CurrentItem会阻塞主线程ANR。
根据网上解决的说法,分析源码:
if (mFirstLayout) {
// We don't have any idea how big we are yet and shouldn't have any pages either.
// Just set things up and let the pending layout handle things.
mCurItem = item;
if (dispatchSelected) {
dispatchOnPageSelected(item);
}
requestLayout();
} else {
populate(item);
scrollToItem(item, smoothScroll, velocity, dispatchSelected);
}
是因为主线程测量滑动距离,绘制UI阻塞,因此通过反射拿到 mFirstLayout变量,每次在setCurrentItem的代码之前设置为true,
try {
Field mFirstLayout = ViewPager.class
.getDeclaredField("mFirstLayout");
mFirstLayout.setAccessible(true);
mFirstLayout.set(vpImg, true);
vpImg.setCurrentItem(num + numCenter, false);
} catch (Exception e) {
e.printStackTrace();
}
根据以上解决方法本应能够解决ANR,可事实依然存在问题,上码:
@Override
public int getCount() {
tvPicSum.setText(vpImg.getCurrentItem() % mOrderListPic.size() +
1 + "/"
+ mOrderListPic.size());
if (mOrderListPic.size() >= 2) {// 当条目超过一个
return Integer.MAX_VALUE;
}
return mOrderListPic.size();
}
这是我的适配器PagerAdapter的getCount()方法,为了能够实现ViewPager的近似无限轮播效果,我们将viewPager的限制页数设置为Integer类型的最大值,但也从而会使ViewPager在setCurrentItem时测量页数太大,绘制UI频繁而阻塞主线程ANR,因此我将数量改成了相对较小些mOrderListPic.size()*40。问题便得带了根本的解决。
版权声明:本文为博主原创文章,未经博主允许不得转载。
项目需求有无限轮播图,之前一直用的没问题,就用之前的放上去了,但是,有个需求是刷新时,把轮播图位置复位,心想不就是setCurrentItem么,so easy!
但....事情却没有那么简单
大家都知道,无限轮播图的做法就是把Adapter中重写getCount返回一个很大的数字,欺骗viewpager有很多,在对position和数据size取模,使数据的position和实际的position对应上,然后使用的时候把当前position设置到getCount数值 的中间,所以setAdapter后setCurrentItem(...),ok,到这里一切顺利
当页面刷新时,得到新数据,对viewpager重新设置数据,然后再次setCurrentItem恢复到初始位置时,问题就来了,这时整个页面完全卡死,过一会就ANR了
懵了......
这么简单的问题竟然会有问题
好了,开始解决问题
经过调试,问题代码就出现在setCurrentItem这行代码,查看ViewPager源码,发现最终调用到这个方法:
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {}
方法里面有行判断:
if (mFirstLayout) {
// We don't have any idea how big we are yet and shouldn't have any pages either.
// Just set things up and let the pending layout handle things.
mCurItem = item;
if (dispatchSelected) {
dispatchOnPageSelected(item);
}
requestLayout();
} else {
populate(item);
scrollToItem(item, smoothScroll, velocity, dispatchSelected);
}
mFirstLayout是一个私有变量,默认为true,第一次设置数据时,mFirstLayout为true,然后在viewpager的
onLayout方法中就被设置成了false
当下次再次setCurrentItem时就进入了else中,这时,else中的代码就会引起UI卡顿,具体原因还未深入研究
但到这就有了思路了,可以利用反射,强行修改mFirstLayout的值为true
try {
Field mFirstLayout = ViewPager.class.getDeclaredField("mFirstLayout");
mFirstLayout.setAccessible(true);
mFirstLayout.set(vp_top, true);
myPagerAdapter.notifyDataSetChanged();
vp_top.setCurrentItem(Integer.MAX_VALUE/4-( Integer.MAX_VALUE/4 % ids_list_data.size() ));
}catch(Exception e) {
e.printStackTrace();
}
好了,到这里问题解决
ps 中间考虑过的方法还有一种,就是获取当前position,经过判断需要位移多受啊能到初始位置,就在刷新时偏移多少,但
是经测试,发现一个问题,在
vp_top.setCurrentItem(vp_top.getCurrentItem()+1);这样偏移一个单位时是没问题的,但是大于1就会卡顿,这个原因
不是很清楚,可能还是跟view的实例化有关,还需要深入研究
关于ViewPager设置属性页setCurrentItem会阻塞主线程ANR总结的更多相关文章
- Kafka producer异步发送在某些情况会阻塞主线程,使用时候慎重
最近发现一个Kafka producer异步发送在某些情况会阻塞主线程,后来在排查解决问题过程中发现这可以算是Kafka的一个说明不恰当的地方. 问题说明 在很多场景下我们会使用异步方式来发送Kafk ...
- join为啥会阻塞主线程?
join使用 上篇我们介绍了CountDownLatch,顺便说到了Thread中的join方法! import java.util.concurrent.TimeUnit; /** * @autho ...
- MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
前面讲了模态对话框和非模态对话框,本节来将一种特殊的对话框--属性页对话框. 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过标签切换各个页面 ...
- VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
前面讲了模态对话框和非模态对话框,本节开始鸡啄米讲一种特殊的对话框--属性页对话框.另外,本套教程所讲大部分对VC++各个版本均可适用或者稍作修改即可,但考虑到终究还是基于VS2010版本的,所以将& ...
- VS2010-MFC(对话框:属性页对话框及相关类的介绍)
转自:http://www.jizhuomi.com/software/164.html 一 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过 ...
- contextmap相当于session之类的 用于设置属性 投放到页面上 contextmap的数据存储在map中
contextmap相当于session之类的 用于设置属性 投放到页面上
- Android之ActionBar、Tabs、Fragment、ViewPager实现标签页切换并缓存页面
感觉 Android 到处都是坑,每个地方都要把人折腾半天. 今天来简单说说 Android之ActionBar.Tabs.Fragment.ViewPager 实现标签页切换并缓存页面 关于他们的介 ...
- 安卓TabLayout+ViewPager实现切页
安卓使用TabLayout+ViewPager+Fragment 实现页面切换,可实现左右滑动切换视图界面和点击切换 可自定义菜单栏是在顶部还是在底部 一.实现效果: 二.实现过程: 2.1 一些重要 ...
- ViewPager之引导页
一.概述 ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换. 本文介绍ViewPager最基础的应用:在多个View之间进行切换,亦即ViewP ...
随机推荐
- Active Directory 域服务(AD DS)
本文内容 概述 工作组架构与域架构 名称空间(Namespace) 对象(Object).容器(Container)与组织单位(Organization Units,OU) 域树(Domain Tre ...
- Office办公 Winrar如何批量把每个文件夹分别压缩成不同的压缩包
右击很多文件夹,添加到压缩文件,然后在文件中勾选把每个文件放到单独的压缩文件中即可
- ActiveMQ面试专题
https://blog.csdn.net/belvine/article/details/79399798
- mycat分库分表 mod-long
转载自:http://blog.csdn.net/sunlihuo/article/details/54574903 下面是配置文件 schema.xml: <?xml version=&quo ...
- LintCode: Fizz Buzz
C++ class Solution { public: /** * param n: As description. * return: A list of strings. */ vector&l ...
- 【SCM】关于Gradle与maven的几篇文章
Gradle官方文档:https://docs.gradle.org/current/userguide/installation.html#sec:download 使用 Gradle 命令行:ht ...
- websocket与canvas[转]
server端还是用tomcat7的方式客户端 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ...
- console.time 简单分析javascript动态加入Dom节点的性能
Bullshit 本来想每天都更新下博客的,可是近期要考试,还有就是自己还是停留在暗自窃喜中吧(这样的想法要改变). 事实上近期总在想.自己要怎么去管理自己的数据,每天的生活都是对自己的数据的增删查改 ...
- Aerospike系列:8:集群宕机演练
1:初始的集群状态 2:关掉192.168.91.133:3000 3:再关掉192.168.91.135:3000 3:再关掉192.168.91.144:3000 5:恢复192.168.91.1 ...
- SSM实战——秒杀系统之Web层Restful url设计、SpringMVC整合、页面设计
一:Spring整合SpringMVC 1:编写web.xml,配置DispatcherServlet <web-app xmlns="http://java.sun.com/xml/ ...