美文网首页常识其他Python
你确定你知道Fragment的懒加载机制?

你确定你知道Fragment的懒加载机制?

作者: Android平头哥 | 来源:发表于2019-03-06 17:51 被阅读344次

又到了一年一季的金三银四,往年的这个时候,也是大多数程序员蠢蠢欲动的时候。 然而,今年的就业形势并没有往年那么明朗,可能你会发现,挂在Boss的简历,没人理,拉钩也是万年不匹配(真的想吐槽吐槽拉钩..)。一方面是整体经济形势下造成的工作岗位的减少,另一方面是求职者的个人水平的原因啦。还是那句话,是金子总会发光的,只要你技术扎实,还怕找不到工作吗? 好吧,扯得有点远

最近投了不少简历,也去了形形色色的公司走了趟。个人发现,大公司更注重你的技术基础,看中你的成长空间,而小公司更在乎你的即战力。所以说,如果你的目标是去大公司发展的话,基础一定要打牢。

今天我想说一说,Fragment的懒加载机制,去了很多公司面试,基本上开胃菜都是Acticity啊,Fragment什么的。如果要问Fragment的话,面试官会从Fragment的生命周期,懒加载机制,和Activity交互这几个角度开始。今天就来写篇文章,Fragment如何实现懒加载,权当一次复习好了。

预加载机制

现在市面上的App绝大部分都采用ViewPager+Fragment来实现卡片的切换,ViewPager会预加载Fragment,ViewPager会预加载当前选中Fragment的前一个Fragment和下一个Fragment,虽然用户可以更快的看到接下来的内容,浏览起来连贯性更好,但是也容易造成资源的浪费。

懒加载机制

由于ViewPager的预加载机制,提前加载好了当前Fragment的相邻两个Fragment,但是这个时候,这两个Fragment是不可见的,而数据却完成了加载,如果是耗时操作,比如大量网络请求、加载图片,很有可能造成界面的卡顿和资源的浪费。在这种情况下,懒加载机制出现了,懒加载机制的意思是需要的时候才去加载,确实有点懒..正常的情况下,我们会在onCreateView()方法里,去做一下数据的请求,那懒加载机制是如何用代码去实现呢?

Fragment的setUserVisibleHint()

是的,要实现Fragment的懒加载,首先需要重写setUserVisibleHint()方法,先来看看这个方法的注释:

 /**
     * Set a hint to the system about whether this fragment's UI is currently visible
     * to the user. This hint defaults to true and is persistent across fragment instance
     
     * and thus has no ordering guarantees with regard to fragment lifecycle method calls.</p>
     *
     * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default)m,false if it is not.
     */
    public void setUserVisibleHint(boolean isVisibleToUser) {
        if (!mUserVisibleHint && isVisibleToUser && mState < STARTED
                && mFragmentManager != null && isAdded()) {
            mFragmentManager.performPendingDeferredStart(this);
        }
        mUserVisibleHint = isVisibleToUser;
        mDeferStart = mState < STARTED && !isVisibleToUser;
    }

简单来说,isVisibleToUser返回true,表示Fragment可见,false不可见。需要注意一下,注释里有句话:This method may be called outside of the fragment lifecycle.,表明这个方法可能会在Fragment的生命周期之外调用。我们重写setUserVisibleHint()方法后,通过getUserVisibleHint()方法拿到isVisibleToUser的值,接着做我们的操作。

大概的原理就是这样,接下在我们就来敲代码吧!
首先,定义我们的TestFragment继承自Fragment。

/**
 * author :  zhangzg
 * time   :  2019/3/6
 * desc   :
 */

public abstract class TempFragment extends Fragment {
    // 布局是否加载完全
    private boolean isPrepare = false;
    // Fragment是否可见
    private boolean isVisible;

    private View mRootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (mRootView == null) {
            mRootView = inflater.inflate(R.layout.fragment_my_scroll,container,false);
        }
        return mRootView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        //  onViewCreated在onCreateView()后调用,view是onCreateView()的返回值,所以在onViewCreated()中将isPrepare置为true最佳。
        isPrepare = true;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        if (getUserVisibleHint()) {
            //  getUserVisibleHint()方法置为true,表明Fragment可见
            isVisible  = true;
        } else {
            isVisible  = false;
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        checkInitData();
    }



    private void checkInitData() {
        if (isVisible && isPrepare) {
            loadData();
        }
    }
    //  子类去实现
    protected abstract  void loadData();
}

我们定义了boolean型变量isPrepare来表示View是否加载完全,isVisible表示Fragment是否可见。我在onViewCreated()方法设置isPrepare=true,很多人往往会在onCreateView()里对isPrepare进行赋值,个人不建议这么做,因为从生命周期方法的调用角度来看,onViewCreated()会在onCreateView()之后调用,并且onViewCreated()的参数View就是onCreateView()方法返回的View,所以在onViewCreated()对isPrepare赋值最佳了。

接着重写setUserVisibleHint()方法,判断getUserVisibleHint()的值,对isVisible进行赋值。

最后在checkInitData()方法里,判断Fragment是否可见并且View加载完全,两条情况都满足的情况下,可以加载数据了。

出于性能考虑,不建议checkInitData()方法放在onCreateView()方法中,因为onCreateView()方法的注释中提到了不建议处理耗时操作。最终,我决定把checkInitData()方法放在onActivityCreated()方法中执行,onActivityCreated()它的含义是,Fragment所依附的Activity的onCreate()已经执行完。

相关文章

网友评论

    本文标题:你确定你知道Fragment的懒加载机制?

    本文链接:https://www.haomeiwen.com/subject/kfkxpqtx.html