调用setCurrentItem()造成ANR

在Android应用开发中,为实现轮播图动态刷新,将轮播逻辑放入网络请求回调中。然而,这引发了第二次进入时的ANR异常。通过调试发现,`setCurrentItem()`方法内部的`setCurrentItemInternal()`导致了问题。解决方法是避免在UI线程中进行阻塞操作,确保平滑滚动参数设置得当。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目的开发中,在首页的轮播图上出现了问题,一开始就是简单的本地图片轮播,ok没问题,但是后来需求改动,要求每次进入都要刷新轮播的个数,于是就把轮播相关的放到了请求成功的回调里,可是问题来了,首次进入可以,但是当第二次回调就会出现ANR的问题,这下就蒙住了,开始调试,发现是 setCurrentItem()这个方法的问题,于是就去度娘搜索,找到了解决办法,原来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();
}catch(Exception e) {
    e.printStackTrace();
}。
(引自https://blog.csdn.net/sandyisbusy/article/details/53792090?locationNum=10&fps=1)
在开发中还遇到了java.lang.NullPointerException: Fragment Attempt to invoke virtual method ‘int android.view.View.getImportantForAccessibility()’ on a null object reference
这个错,一开始怎么也想不到错在哪里了,后来检查adapter的getView()的方法才发现原来返回值是null.....,把contentview返回就好了。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值