Activity 与 Fragment 生命周期对照
image.png切换fragment典型代码
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.fragment_recent, recentFragment);
transaction.commit();
FragmentTransaction add 和 replace 区别
- 覆盖原fragment, 添加入一个新fragment后, 原来的fragment仍然存活
- replace 是先remove掉相同id的所有fragment,然后在add当前的这个fragment
从性能出发, 推荐使用replace
Fragment延迟加载
ViewPager的预加载问题。ViewPager会默认在当前页面的左右两边至少预加载一个页面以保证ViewPager的流畅性。
由于ViewPager的预加载原因,即使在其它Fragment不可见的情况下也会去进行网络请求加载数据。而如果此时用户根本就没有去滑动ViewPager就退出了应用或者切换到了其他页面。那么对于这个不可见的Fragment中的网络请求既浪费了流量也浪费了手机和服务器的性能。
因此,Fragment中为提供了一个 setUserVisibleHint 方法,这个方法中有一个isVisibleToUser的boolean类型的参数,表示当前的Fragment是否对用户可见,可以根据该参数进行数据加载。
注意:
- setUserVisibleHint在Fragment的onAttach之前就已经被调用了。
- ViewPager2中,默认关闭了预加载机制。因此延迟加载也没有任何意义了
- offScreenPageLimit(1)可进行设置
setMaxLifecycle
Androidx并将androidx版本升级到1.1.0之后setUserVisibleHint 方法已被标记为废弃,我们可以跟紧setMaxLifecycle(@NonNull Fragment fragment, @NonNull Lifecycle.State state) 进行控制
Lifecycle生命周期
- DESTORYED
- INITALIZED
- CREATED
- STARTERD
- RESUMED
(setMaxLifecycle中接收的生命周期状态要求不能低于CREATED,否则会抛出一个IllegalArgumentException的异常)
通过setMaxLifecycle方法可以精确控制Fragment生命周期的状态,如果Fragment的生命周期状态小于被设置的最大生命周期,则当前Fragment的生命周期会执行到被设置的最大生命周期,反之,如果Fragment的生命周期状态大于被设置的最大生命周期,那么则会回退到被设置的最大生命周期。
Lifecycle.State.CREATED
fragment = TestLifecycleFragment.getInstance(Card.DECK[0], 0)
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.ll_fragment, fragment)
fragmentTransaction.setMaxLifecycle(fragment, Lifecycle.State.CREATED)
fragmentTransaction.commit()
该Fragment的生命周期仅仅执行到了onCreate就没再往下执行了。并且Activity中没有加载出来当前Fragment。
假设Fragment已经执行到了onResume,此时再为Fragment设置一个CREATED,会执行onPause->onStop->onDestoryView。也就是回退到了onCreate的状态。
Lifecycle.State.STARTED
Fragment已经执行到了onResume方法再为其设置最大生命周期为STARTED,Fragment执行了onPause方法,也就是生命周期退回到了onStart。
Lifecycle.State.RESUMED
已经执行了onResume后的Fragment,再去设置最大生命周期为RESUMED,不会执行任何代码。
androidx 延迟加载
Androidx 1.1.0版本中的FragmentStatePagerAdapter(@NonNull FragmentManager fm, @Behavior int behavior) 已经帮我们实现了。
behavior
- BEHAVIOR_SET_USER_VISIBLE_HINT:Fragment改变的时候,setUserVisibleHint方法会被调用,也就是这个参数其实是为了兼容以前的老代码。
- BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT:只有当前显示的Fragment会被执行到onResume,而其它Fragment的生命周期都只会执行到onStart.
[整理自],吹爆这篇(https://juejin.im/post/5e085dafe51d45580769a1eb#heading-2)
网友评论