存储架构

Fragment新功能,setMaxLifecycle了解一下

微信扫一扫,分享到朋友圈

Fragment新功能,setMaxLifecycle了解一下
0

前言

看了一篇关于ViewPager2软文后,我发现最新的 Fragment 代码淘汰了 setUserVisibleHint 方法,转而支持用 setMaxLifecycle 方法, setMaxLifecycle 言外之意是 设置最大生命周期 ,懂行的人应该知道, Fragment 一直都是无法直接设置生命周期,必须通过 addattachremovedetachshowhide 方法间接干预,本来就此功能,简单介绍一下 setMaxLifecycle 的原理和上手效果;

阅读指南:

  • 本文基于 androidx 1.1.0-alpha07 版本的 fragment 进行,也是支持 setMaxLifecycle 的最低版本
  • 本文会根据 FragmentPagerAdapter 进行 setMaxLifecycle 示例应用讲解

基本介绍

setMaxLifecycle 定义在 FragmentTransaction 中,和之前的 addattachremovedetachshowhide 等方法是并列关系;

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 ,所以该方法可用的参数有 CREATEDSTARTEDRESUMEDState生命周期方法 有何区别,下面简单解释一下:

生命周期状态理解

在Fragment中,定义了五种 State ,这里的 State 并非上面说 Lifecycle.State ,但是逻辑基本上是一致的;

  • INITIALIZING 初始状态

  • CREATED 已创建状态

  • ACTIVITY_CREATED 完全创建,但是没有started

  • STARTED 创建并启动,可见不可操作

  • RESUMED 创建启动并可操作[图片上传中…(image-1940e7-1557923091355-0)]

    <figcaption></figcaption>

本文内容只对 CREATEDSTARTEDRESUMED 这三个状态讲解,由于Fragment中定义的 mStateLifecycle.State 不是同一状态,在本文视为同一概念;

与生命周期对应关系

各位肯定都知道Fragment生命周期有 onDestoryonStop 等方法,但是状态却没有这么多,那么如何标识状态和对应关系,下面给出对应关系;

首先,我把生命周期方法从 onCerate -> onCretateView -> onStart -> onResume -> onPause -> onStop -> onDestoryView -> onDestory 视为从小到大排序;

同样的,我们把生命周期状态 CREATED -> STARTED -> RESUMED 视为从小到大排序;

  • CREATED状态

CREATED 即已创建状态,狭义的理解是生命周期方法走到 onCerate ,如果当前fragment状态已大于 CREATED ,则会使fragment生命周期方法走到 onDestoryView ,如果小于 CREATED ,则走到 onCerate ;所以 CREATED 有两种情况;

  • STARTED状态

同理, STARTED 状态也有两种情况,如果当前fragment状态已大于 STARTED ,则会使fragment生命周期方法走到 onPause ,如果小于 CREATED ,则走到 onStart

  • RESUMED状态

RESUMED 表示的状态比较特殊,只代表 onResume 状态,无论大到小还是小到大,最终都是停留到 onResume 状态;

以上生命周期状态扭转结论基于 FragmentManagerImpl.moveToState() 方法提取,如有误导,请指教

如何使用

setMaxLifecycle 可以单独使用,也可以配合 add 等方法组合使用,首先,我们分析单独执行 add 命令的状态变化:

单独执行add操作

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.commit();

add配合setMaxLifecycle(Lifecycle.State.CREATED)

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.CREATED);
fragmentTransaction.commit();

add配合setMaxLifecycle(Lifecycle.State.STARTED)

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.STARTED);
fragmentTransaction.commit();

add配合setMaxLifecycle(Lifecycle.State.RESUMED)

FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.RESUMED);
fragmentTransaction.commit();

单独使用setMaxLifecycle

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setMaxLifecycle(cardFragment, xxx);
fragmentTransaction.commit();
  • RESUMED 状态的Fragment进行操作 CREATED 操作

  • RESUMED 状态的Fragment进行操作 STARTED 操作

  • RESUMED 状态的Fragment进行操作 CREATED 操作,在进行 STARTED 操作

由于篇幅原因,就不一一介绍各种组合情况,只要弄清楚生命周期状态,不论是状态是升还是降,不论组合还是单用,你都可以驾驭;

FragmentPagerAdapter变动

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

FragmentPagerAdapter

public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0;
public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1;

private final int mBehavior;

public FragmentPagerAdapter(@NonNull FragmentManager fm) {
    this(fm, BEHAVIOR_SET_USER_VISIBLE_HINT);
}

public FragmentPagerAdapter(@NonNull FragmentManager fm,@Behavior int behavior) {
    mFragmentManager = fm;
    mBehavior = behavior;
}

最新的 FragmentPagerAdapter 用一个 mBehavior 来控制 setUserVisibleHintsetMaxLifecycle 二选一的局面; mBehavior 在构造方法中指定;

从代码可以看出,用 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 方法;

懒加载新方案

综上,过去使用 setUserVisibleHint 来控制Fragment懒加载,在最新版的FragmentPagerAdapter里有新思路,可以切换到 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 模式,在Fragment onResume 里判断,更符合显示逻辑;

切换到 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 模式,需要调用俩参数的构造方法:

new FragmentPagerAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

总结

破事水了小半天,本文到底说了什么内容,还是做个总结吧:

首先使用 setMaxLifecycle 能进一步的控制 Fragment 生命周期,一句话形容就是对 addattach 等命令的补充;

其次该功能在官方控件中得以运用,改善了 ViewPager + Fragment 的使用体验,懒加载注意点;

最后鼓励大家(主要是自己)多看源码,夯实基础,方能不变应万变,本文结束。

最后

针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

  • Android前沿技术大纲

  • 全套体系化高级架构视频

资料领取: 点赞+加群免费获取Android IOC架构设计

加群Android IOC架构设计领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

阅读原文...


微信扫一扫,分享到朋友圈

Fragment新功能,setMaxLifecycle了解一下
0

简书

SendBird chat platform for developers adds 50M to their raise

上一篇

携程,人人十年架构师:高并发下RabbitMq消息中间件你应该介么玩

下一篇

评论已经被关闭。

插入图片

热门分类

往期推荐

Fragment新功能,setMaxLifecycle了解一下

长按储存图像,分享给朋友