Fragment最新生命周期管理方法

Fragment生命周期介绍

开发Android的人都知道fragment是Android中常用管理碎片的组件,虽然不是四大组件之一,但地位已和四大组件相当,甚至有的使用一个Activity加多个Fragment即可构建一个漂亮的APP。因此Fragment地位可见一斑。在学习了解Fragment生命周期改进之前,先来看看fragment的生命周期:

在这里插入图片描述
图中介绍的很清楚了,不过在开发中进场用到的也就是以下几个方法:

  • onCreate()
    初始化Fragment。可通过参数savedInstanceState获取之前保存的值。
  • onCreateView()
    初始化Fragment的布局。加载布局和查找控件的操作通常在此完成,此时页面刚刚加载进来。因此不建议执行耗时的操作,比如读取数据库数据列表。
  • onActivityCreated()
    与Fragment绑定的Activity的onCreate()方法已经执行完成并返回,在该方法内可以进行与Activity交互的UI操作,所以在该方法之前Activity的onCreate方法并未执行完成,如果提前进行交互操作,会引发空指针异常。
  • onStart()
    执行该方法时,Fragment由不可见变为可见状态。
  • onResume()
    执行该方法时,Fragment处于活动状态,用户可与之交互。
  • onPause()
    执行该方法时,Fragment处于暂停状态,但依然可见,用户不能与之交互。
  • onStop()
    执行该方法时,Fragment完全不可见。
  • onDestroyView()
    销毁与Fragment有关的视图,但未与Activity解除绑定,依然可以通过onCreateView方法重新创建视图。通常在ViewPager+Fragment的方式下会调用此方法。
  • onDestroy()
    销毁Fragment。通常按Back键退出或者Fragment被回收时调用此方法。

Fragment生命周期执行流程

Fragment正常创建执行的生命周期:

onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume();

Fragment变为不可见状态(锁屏、回到桌面、被Activity完全覆盖):

onPause()->onSaveInstanceState()->onStop()

Fragment可见但不可交互(页面显示dialog,popwindow等):

onPause()->onSaveInstanceState()

Fragment由不可见变为可见(从桌面返回,解锁):

onStart()->onResume()

Fragment从不可交互变为可交互(dialog、popwindow消失):

onResume()

Fragment销毁(activity页面关闭):

onPause()->onStop()->onDestoryView()->onDestory()

从上面可以看出有些生命周期是相对应的,比如

onStart()-onStop()
onResume()-onPause()

也就是说执行了像onstop()生命周期方法后再次回到页面一定会执行onStart()方法,同理onPause()也是一样
同时在使用Fragment时也发现Fragment的生命周期方法并不是独立的,它是随着Activity的生命周期而执行自己相对应的生命周期。

Fragment最新生命周期方法改进

针对上面的问题,Google提出了Fragment手动干预生命周期的方法setMaxLifecycle,该方法是在FragmentTransaction类中,通常和add()方法一起使用:
FragmentTransaction

public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
        @NonNull Lifecycle.State state) {
    addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
return this;
}

参数说明:

  • fragment即需要操作的Fragment对象,前提条件是这个fragment必须已经加到FragmentManager中;
  • state Lifecycle.State枚举类型,该参数的使用条件是至少是Lifecycle.State.CREATED,否则报IllegalArgumentException异常

Lifecycle.State一共有五个状态,最低要求是Lifecycle.State.CREATED,所以该方法可用的参数有CREATEDSTARTEDRESUMED,State和生命周期方法有何区别,下面简单解释一下:

  • INITIALIZED 初始化状态 fragment已经创建但依附的activity执行onCreate()还没有关联时
  • CREATED 已创建状态 狭义的理解是生命周期方法走到onCreate,有两种情况,如果当前fragment状态已大于CREATED,则会使生命周期方法走到onDestoryView,如果小于CREATED,则走到onCreate
  • STARTED 创建并启动,可见不可操作 也有两种情况,如果当前fragment状态已大于STARTED,则会使生命周期方法走到onPause,如果小于CREATED,则走到onStart
  • RESUMED 创建启动并可操作 RESUMED表示的状态比较特殊,只代表onResume状态,无论大到小还是小到大,最终都是停留到onResume状态;
  • DESTROYED 销毁状态 销毁后将不会分发任何事件,对应生命周期方法是onDestroy

使用方法
针对如上的状态说明该如何使用呢?
setMaxLifecycle可以单独使用,也可以配合add,replace等方法组合使用。

首先,我们分析单独执行replace命令的状态变化:

FragmentManager supportFragmentManager = getSupportFragmentManager();//开启事务
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//碎片
fragmentTransaction.replace(R.id.share_frame_layout, mSearchFragment);
fragmentTransaction.commit();

在这里插入图片描述

接着使用setMaxLifecycle配合replace方法,同时设置状态为CREATED

FragmentManager supportFragmentManager = getSupportFragmentManager();//开启事务
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//碎片
fragmentTransaction.replace(R.id.share_frame_layout, mSearchFragment);
fragmentTransaction.setMaxLifecycle(mSearchFragment, Lifecycle.State.CREATED);
fragmentTransaction.commit();

在这里插入图片描述
接着将setMaxLifecycle的状态设为STARTED

FragmentManager supportFragmentManager = getSupportFragmentManager();//开启事务
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//碎片
fragmentTransaction.replace(R.id.share_frame_layout, mSearchFragment);
fragmentTransaction.setMaxLifecycle(mSearchFragment, Lifecycle.State.STARTED);
fragmentTransaction.commit();

在这里插入图片描述
然后将setMaxLifecycle的状态设为RESUMED

FragmentManager supportFragmentManager = getSupportFragmentManager();//开启事务
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//碎片
fragmentTransaction.replace(R.id.share_frame_layout, mSearchFragment);
fragmentTransaction.setMaxLifecycle(mSearchFragment, Lifecycle.State.RESUMED);
fragmentTransaction.commit();

在这里插入图片描述
其他两个状态尝试设置了,直接崩溃并报以下异常错误:
在这里插入图片描述
下面尝试单独使用setMaxLifecycle

  • fragmentRESUMED状态设置CREATED
FragmentManager supportFragmentManager = getSupportFragmentManager();//开启事务
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();//碎片
fragmentTransaction.setMaxLifecycle(mSearchFragment, Lifecycle.State.CREATED);
fragmentTransaction.commit();

在这里插入图片描述

  • fragmentRESUMED状态设置STARTED
    在这里插入图片描述
    由于篇幅原因,就不一一尝试其他组合了,有兴趣的可以自己尝试

FragmentPagerAdapter变动以及懒加载的修改

由于setMaxLifecycle带来了生命周期设置,替换掉了老旧的setUserVisibleHint方法,所以在FragmentPagerAdapter中也进行了适配
FragmentPagerAdapter

/**
* Constructor for {@link FragmentPagerAdapter}.
*
* If {@link #BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT} is passed in, then only the current
 * Fragment is in the {@link Lifecycle.State#RESUMED} state. All other fragments are capped at
* {@link Lifecycle.State#STARTED}. If {@link #BEHAVIOR_SET_USER_VISIBLE_HINT} is passed, all
* fragments are in the {@link Lifecycle.State#RESUMED} state and there will be callbacks to
 * {@link Fragment#setUserVisibleHint(boolean)}.
 *
* @param fm fragment manager that will interact with this adapter
* @param behavior determines if only current fragments are in a resumed state
 */
public FragmentPagerAdapter(@NonNull FragmentManager fm,@Behavior int behavior) {
     mFragmentManager = fm;
     mBehavior = behavior;
}

增加了一个behavior的参数,瞬间解决了自己编写懒加载的代码逻辑,真是爽歪歪!
那具体是怎么实现的呢?看源码:
在这里插入图片描述

从代码可以看出,用setMaxLifecycle(mCurrentPrimaryItem, Lifecycle.State.STARTED)替代setUserVisibleHint(false),用setMaxLifecycle(fragment, Lifecycle.State.RESUMED)替代setUserVisibleHint(true)

为什么要用Lifecycle.State.STARTED?因为这里本质上用的是add+Lifecycle.State.STARTEDattach+Lifecycle.State.STARTED组合;

最终的结果当Fragment不可见时只会走到生命周期onStart方法,不会走onResume方法,这样便可以在Fragment基类的onResume()方法中设置方法,从而方便快捷的实现懒加载,而且我觉得这才是Fragment生命周期变化最大的好处;

懒加载新的实现方案

综上,过去使用setUserVisibleHint来控制Fragment懒加载,现在可以通过在Fragment的基类onResume方法中做相关操作,简单的看下基类的设置:
在这里插入图片描述
在创建PagerAdapter时通过传入BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT来轻松愉快的实现

new CollectPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, titleLists)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FragmentAndroid 中一种非常重要的 UI 组件,它可以嵌入到 Activity 中使用。与 Activity 一样,每个 Fragment 都有自己的生命周期,包括创建、销毁、暂停、恢复等等。 在 Fragment生命周期中,主要有以下几个方法: 1. onAttach():当 Fragment 被添加到 Activity 中时调用,此时可以获取到该 Fragment 所依赖的 Activity。 2. onCreate():当 Fragment 第一次创建时调用,可以进行一些初始化操作,如设置布局等等。 3. onCreateView():当 Fragment 第一次绘制其布局时调用,可以通过该方法返回布局的 View 对象。 4. onActivityCreated():当 Fragment 所依赖的 Activity 完成 onCreate() 方法后调用,此时可以进行一些与 Activity 相关的初始化操作。 5. onStart():当 Fragment 可见但不在前台时调用。 6. onResume():当 Fragment 可见且在前台时调用。 7. onPause():当 Fragment 不可见但仍在前台时调用。 8. onStop():当 Fragment 不可见且不在前台时调用。 9. onDestroyView():当 Fragment 的布局被移除时调用。 10. onDestroy():当 Fragment 被销毁时调用。 11. onDetach():当 Fragment 被从 Activity 中移除时调用。 在使用 Fragment 时,需要注意以下几点: 1. 通过 FragmentTransaction 进行 Fragment 的添加、替换或移除操作。 2. 避免在 Fragment 中持有 Activity 的引用,以免内存泄漏。 3. 避免在 Fragment生命周期方法中进行耗时操作,以免影响用户体验。 4. 对于需要保存状态的数据,可以通过 onSaveInstanceState() 方法进行保存和恢复。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值