android - viewPager滑动浏览一组大图,滑动倒数第二张时请求新数据追加数据……

 昆哥2502852107 发布于 2022-11-01 14:17
  • 在listView中点击例如“美女图片”后打开一个largeActivity;

  • largeActivity中有一个viewPager实现左右滑动浏览大图;

  • 在largeActivity打开的时候会通过okHttp从服务器请求一组5张图片链接,图片通过glide加载在viewPager中实现左右滑动浏览;

  • 因为每次网络请求只能返回5张图片链接,所以我在监听每次滑动viewPager的时候判断当前 postion小于存储图片链接的imageList.size() -1的时候,也就是每次滑动到倒数第二张的时候去网络请求下一组图片的链接;

  • 然后通过add将新请求到的图片链接添加进imageList,然后再执行一次
    pagerAdapter.notifyDataSetChanged()来实现viewPager继续滑动浏览新请求到的图片。

现在问题是如果用户以正常速度滑动viewPager来浏览每张图片的时候是没有任何问题的,但是如果用户飞速滑动viewPager的进行浏览的时候就会出现在某一次请求新数据后就会出现APP崩溃的情况;错误信息在两部不同的手机上报错不一样,但是都是在相同的情况下崩溃。Google遍都没有找到解决办法

华为荣耀报错如下:

通过华为手机的报错在网上找到通过设置 android:hardwareAccelerated="false"
来关闭硬件加速的办法,但是通过测试在快速滑动时还是会导致APP崩溃自动重启的情况

乐视max2报错如下:

03-21 05:42:44.071 18730-18730/com.abcd.reader.abcdreader E/InputEventReceiver: Exception dispatching input event.
03-21 05:42:44.071 18730-18730/com.abcd.reader.abcdreader E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
03-21 05:42:44.084 18730-18730/com.abcd.reader.abcdreader E/MessageQueue-JNI: java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 25, found: 30 Pager id: com.abcd.reader.abcdreader:id/vp_pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.abcd.reader.abcdreader.adapter.FollowDetailViewPagerAdapter

通过乐视手机的报错怀疑是当新请求的数据add进imageList后,但是还没来得及执行notifyDataSetChanged,刚好在这时用户在滑动viewPager的时候导致的;为了验证猜测我修改了在当前 postion小于存储图片链接的imageList.size() -2的时候,也就是每次滑动到倒数第三张的时候去网络请求下一组图片的链接;给imageList.add和notifyDataSetChanged预留了充分的执行时间,这时候再次测试问题消失,华为手机和乐视手机均没有再出现APP崩溃重启的情况


但是我这个服务器请求回来的数据是不固定的,有时候可能每次返回5条,有时候10条,有时候只有1条,所以我现在的解决办法并不能彻底解决
烦请老师们给予指点一二,万分感谢!

5 个回答
  • 看问题,题主是在viewpager滑动监听的方法里面做网络请求,
    如果使用者快速左右滑动viewpager,很可能多次执行该回调。
    而之前的网络请求还在进行中,再次请求也就崩溃了。
    如果是这个原因造成的话,你可以增加一个标记,如果当前请求正在进行中,在没有得到正确或错误的回调前,不再进行新的网络请求。
    至于返回不条目数不固定的问题,如果你请求5张图片,服务器只返回3张,说明服务器图片已经全给你了,你的网络请求也就不要执行了

    2022-11-02 08:41 回答
  • 策略就错了,每次只返回5个image的url是为什么?难道是为了节省流量吗?最大的浪费是三次握手的创建过程,上来就应该拿到所有的url,然后自己控制图片缓存。
    你每次到倒数第二张再去请求,也不怕麻烦.....

    2022-11-02 08:51 回答
  • 不知道是不是我理解错了,但images.size()-1不是倒数第二张,而是最后一张

    建议把从服务器拉取条目的逻辑写到Adapter的getItem;

     @Override
            public Fragment getItem(int position) {
                if(getCount()-1 == position){
                    //在此处拉取
                }
                return ArrayListFragment.newInstance(position);
            }
    2022-11-02 08:52 回答
  • 具体错误原因我暂时无法帮你定位,我给你另一个实现的思路,可以尝试使用RecycleView来实现同样的效果。

    2022-11-02 08:53 回答
  • 大胆估计一下应该是线程安全问题,可以尝试一下以下修改,获取新数据时,使用post方法去做更新,即
    viewPager.post()notifyDataSetChanged放到post任务里去。还没亲自验证,如果不可以,也麻烦你告诉我一声,我再看看。

    2022-11-02 08:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有