android fragment懒加载细致解析

来源:互联网 发布:威锋网 mac office 编辑:程序博客网 时间:2024/05/16 07:29

前言:

最近在做项目优化,正好处理到这块,所以决定重新写篇细致点的关于fragment懒加载的博客。fragment的懒加载对于项目的性能也有优化作用,流量对于手机端而言还是蛮重要的虽然现在手机在很多时候所处于的网络环境都是使用wifi。当然你获取数据肯定要开启线程获取数据,这对于手机而言也是性能消耗。
好了,说了这么多废话该进入正题了,当然要懂一点fragment懒加载的,可以看我前期写的一篇博客
android懒加载
当然按照上面那篇博客那样处理还是不行的,或者说是细节还不够,所以接下来就说下在项目中具体怎么处理。
我这里就直接讲解demo如何处理了,一共是3个tab,先上一个basefragment的代码。再根据日志来讲解。
/** * 懒加载fragment */public abstract class LazyLoadBaseFragment extends Fragment {    protected boolean isVisible;    private boolean isPrepared;    private boolean isFirst = true;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        isPrepared = true;        lazyLoad();    }    @Override    public void setUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);        if (getUserVisibleHint()) {            isVisible = true;            lazyLoad();        } else {            isVisible = false;            onInvisible();        }    }    @Override    public void onDestroy() {        super.onDestroy();    }    protected void lazyLoad() {        if (!isPrepared || !isVisible || !isFirst) {            return;        }        getData();        isFirst = false;    }    protected void onInvisible() {    }    public abstract void getData();}

从上面的代码可以看到,我这有3个标识,
1.isFirst---用于判断是否已经加载过数据了,用于缓存之后不再加载数据的
2.isVisible 在setUserVisibleHint(boolean isVisibleToUser)方法中判断fragment中的view已经显示没
3.isPrepared 判断fragment的onActivityCreated(Bundle saveInstanceState)方法是否已经被执行(为什么需要这个呢,后面分析的时候会说到)

由于这台机子没有运行环境(网络太慢升级有点麻烦),所以就直接拿在公司的测试时候的截图来说了。
正常情况下fragment从tab1滑动到tab2再滑动到tab3
tab3的fragment的日志情况

BalanceFragment就相当于我们的tab3
从上面的日志可以看到,setUserVisibleHint会先执行一次,然后当我们的tab3要执行onResume显示到前台的时候又会执行一次setUserVisibleHint,第一次不用说,getUserVisibleHint()拿到的值肯定是false,显示到前台之后才为true,这样我们再去拿数据.所以我刚开始的思路是,执行完oncreateview()之后再加上getUserVisibleHint()为true的时候才去获取数据。这样处理的话从tab1一直滑动到tab3是没有问题的。但是有种情况,从tab1直接点击到tab3就会出现问题了,原因是当页面显示tab1的时候,viewpager的默认机制是缓存下一个fragment和上一个fragment,所以tab2会被初始化,但是tab3就不会。看下图的Log日志就清楚了。

可以看到在tab3的onResume()执行之后并没有去执行setUserVisibleHint()方法,会直接在onCreate()之后就执行,与一开始的思路就相矛盾了,因为一开始的思路是执行完onCreateView()和setUserVisibleHint()方法返回true之后才去拿数据,因为在onCreateVIew()还没执行,setUserVisibleHint()就已经先返回true了,这样就会导致直接点击tab3不会调用获取数据的方法,导致页面一直停留在loading动画的页面。
所以这样我们的onActivityCreated()方法中的isPrepared标识就要起作用了,刚开始测试的时候忘记了打印onActivityCreated()回调的日志信息,不过看下面的日志信息就能懂了。

可以看到onCreateView()是执行在onActivityCreated()之后的,所以我们在onActivityCreated()中增加一个标识来判断fragment是否显示,显示就获取数据。相当于把onCreateView()的标识给替换到onActivityCreated()中。这样纵使是直接切换,setUserVisibleHint()执行在onCreateView()之前,我们也可以通过onActivityCreated()来判断是否是在fragment显示的时候才去获取数据。
其实这也是对fragment生命周期的一种理解与运用方式,所以很多时候基础还是很重要的。
这样就解决了,之前直接点击没有被viewpager提前缓存的fragment而出现不能加载数据的问题。
刚开始设计的错误思路的代码也贴下,这样方便理解




好了,fragment的懒加载就说到这里了,由于自己这台电脑跑demo跑不了,所以日志输出的图不太完美,不过相信仔细看下还是能懂的,如果要demo文章末尾有下载链接

懒加载Demo:
懒加载demo

原创粉丝点击