ViewPager的缓存机制和懒加载实现

简介: ViewPager的缓存机制和懒加载实现

在开发的时候经常使用ViewPager + Fragment ,但是你真的了解他是怎么执行的吗,是时候进行一下总结了。



1,ViewPager的适配器



FragementPagerAdapter和FragmentStatePagerAdapter


FragmentPagerAdapter中,即使fragment不可见了,他的事他实例还是存在于内存中,当 fragment比较多的时候,会占用较大的内存.

FragmentStatePagerAdapter,当fragment不可见时,可能会将fragment的实例会销毁,所以内存占会小一些


2,ViewPager 的缓存机制



ViwePager 的缓存机制会默认缓存旁边的页面,是为了让页面更加流畅.在缓存旁边页面的时候会执行到onCreateView方法,如果你两个碎片的onCreateView 中都有执行请求数据的时候,旁边的页面也会发送请求,这样就会造成网络请求的一些问题。

使用setOffscreenPagerLimit方法可以设置缓存页面的个数,默认为1,就算你传入负数他还是默认缓存旁边页面,也就是1

由于ViewPager的默认缓存是1,所以ViewPager中至少会预加载一个页面的数据。如果页面有请求数据或者下载数据的时候,这就会影响当前显示的页面。

我们知道在碎片中 只有在onCreateView方法中才可以拿到View 然后加载控件进行一些数据的设置.但是当碎片在ViewPager中的时候,缓存机制会导致旁边的页面中的onCreateView方法执行,这就是我们不想看到的结果。

Fragment里面有一个方法 setUserVisibleHint(boolean isVisibleToUser)方法,这个方法可以判断当前页面是否对用户可见。

还有一点,当ViewPager缓存了旁边的那个碎片之后,那个碎片执行onCreateView之后,他碎片的生命周期会失效。当他被缓存抛弃的时候这个碎片就会被销毁。直到他又一次被缓存或者当他可见的时候才会执行onCreateView方法。


3,懒加载实现



定义所有碎片的基类,也就是让所有碎片继承这个类,他是一个抽象类


public abstract class FragmentFactory extends Fragment {
    private boolean isViewInitFinished;
//当Fragment所在的Activity被启动完成后回调该方法
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isViewInitFinished = true;
    }
// 当前页面是否可见
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser && isViewInitFinished){
            getData();
        }
    }
    public abstract void getData();
}


让ViewPager里面要显示的碎片继承这个类并实现他的方法,在这个方法里面就可以去执行你的逻辑了。记住当实现懒加载的时候就不要在onCreateView方法执行逻辑了。当碎片加载的时候会调用父类的setUserVisibleHint方法。后判断是否是当前页面,如果是就可以在重新父类的方法中进行操作了。

SetUserVisibleHint方法是执行在最前面的,他会在ViewPager里面Fragment生命周期还没执行的时候调用.

请注意SetUserVisibleHint方法调用的次数,在刚开始的时候会根据你设置的ViewPager的缓存个数去调用SetUserVisibleHint方法,然后Fragment显示后会在调用一次SetUserVisibleHint方法。也就是说在Fragment生命周期之前ViewPager会根据缓存个数去调用SetUserVisibleHint方法。当调用完成后,Fragment的生命周期会开始,这个时候Viewpager就会再次调用SetUserVisibleHint方法判断当前的fragment是否被显示。所以在SetUserVisibleHint中判断是否是当前页面的时候 都要判断一下 在onActivityCreated中的布尔变量是否为真,必须在这个布尔为真的时候才可以去判断当前Fragment有没有显示。


这种懒加载在官方文档中给出了明确的说明


/**
 * Created by hjm on 2017/4/13 15:40.
 */
public abstract class BaseFragment extends Fragment {
    private boolean isViewInitFinished;
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isViewInitFinished = true;
    }
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        requestData(isVisibleToUser);
    }
    public void requestData(boolean isVisibleToUser){
        if(isViewInitFinished && isVisibleToUser){
            getData();
        }
    }
    /**
     *  this moment the fragment is visiable to user, so request data
##### #### #### #### #### **     */**
    public abstract void getData();
}


本人也是新手,如有错误请指出,谢谢!


目录
打赏
0
0
0
0
0
分享
相关文章
PyTorch CUDA内存管理优化:深度理解GPU资源分配与缓存机制
本文深入探讨了PyTorch中GPU内存管理的核心机制,特别是CUDA缓存分配器的作用与优化策略。文章分析了常见的“CUDA out of memory”问题及其成因,并通过实际案例(如Llama 1B模型训练)展示了内存分配模式。PyTorch的缓存分配器通过内存池化、延迟释放和碎片化优化等技术,显著提升了内存使用效率,减少了系统调用开销。此外,文章还介绍了高级优化方法,包括混合精度训练、梯度检查点技术及自定义内存分配器配置。这些策略有助于开发者在有限硬件资源下实现更高性能的深度学习模型训练与推理。
676 0
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
文章介绍了MyBatis的缓存机制,包括一级缓存和二级缓存的配置和使用,以及如何整合第三方缓存EHCache。详细解释了一级缓存的生命周期、二级缓存的开启条件和配置属性,以及如何通过ehcache.xml配置文件和logback.xml日志配置文件来实现EHCache的整合。
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
Web服务器的缓存机制与内容分发网络(CDN)
【8月更文第28天】随着互联网应用的发展,用户对网站响应速度的要求越来越高。为了提升用户体验,Web服务器通常会采用多种技术手段来优化页面加载速度,其中最重要的两种技术就是缓存机制和内容分发网络(CDN)。本文将深入探讨这两种技术的工作原理及其实现方法,并通过具体的代码示例加以说明。
869 1
【赵渝强老师】Spark RDD的缓存机制
Spark RDD通过`persist`或`cache`方法可将计算结果缓存,但并非立即生效,而是在触发action时才缓存到内存中供重用。`cache`方法实际调用了`persist(StorageLevel.MEMORY_ONLY)`。RDD缓存可能因内存不足被删除,建议结合检查点机制保证容错。示例中,读取大文件并多次调用`count`,使用缓存后执行效率显著提升,最后一次计算仅耗时98ms。
117 0
【赵渝强老师】Spark RDD的缓存机制
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
298 4
MyBatis缓存机制
MyBatis提供两级缓存机制:一级缓存(Local Cache)默认开启,作用范围为SqlSession,重复查询时直接从缓存读取;二级缓存(Second Level Cache)需手动开启,作用于Mapper级别,支持跨SqlSession共享数据,减少数据库访问,提升性能。
116 1
缓存代理服务器的实现机制和技术选型
缓存代理服务器是一种特殊的代理服务器,其主要功能是缓存从目标服务器(通常是Web服务器)获取的数据,并在客户端再次请求相同数据时直接提供缓存的数据。通过缓存代理服务器可以加快访问速度并减轻目标服务器的负载。
455 77
Nginx代理缓存机制
【10月更文挑战第2天】
236 4
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问