引入
每个fragment都有他自己的生命周期,当用户操作add,remove,replece时,fragment的生命周期都会发生变化。我在想到底是什么场景需要这个呢?比如:如果用tab切换fragment的话,你们是习惯使用replace还是show,hide呢?一般我们为了体验上能快一些都会采用show、hide,因为replace相当于remove,add,show,每次都会重新创建一个新的实例,创建实例就涉及view的创建绘制等,性能肯定比不上show,hide来得好。但是我这边的旧项目就是用的replace,为了提高性能,我想把他改成show,hide的方式来,这时候Lifecycle就派上了用场。
使用
我创建了一个界面只有按钮,每click一次。将会切换一次fragment,以此来检验fragment生命周期的变化
public class FragmentDemoActivity extends AppCompatActivity {
private FragmentManager mFragmentManager;
public static final String TAG = "FragmentDemoActivity";
private Button mBtn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragmentManager = getSupportFragmentManager();
mBtn = findViewById(R.id.btn);
mBtn.setText("chang fragment");
Fragment f1 = new Fragment1();
Fragment f2 = new Fragment2();
mBtn.setAllCaps(false);
mBtn.setOnClickListener(v -> {
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
if (!f1.isAdded()){
fragmentTransaction.add(R.id.container, f1, "fragment1");
}else if (!f2.isAdded()){
fragmentTransaction.add(R.id.container, f2, "fragment2");
}
if (!f1.isVisible()){
fragmentTransaction.show(f1).setMaxLifecycle(f1, Lifecycle.State.RESUMED);
if (f2.isVisible()){
fragmentTransaction.hide(f2).setMaxLifecycle(f2, Lifecycle.State.CREATED);
}
}else if (!f2.isVisible()){
fragmentTransaction.show(f2).setMaxLifecycle(f2, Lifecycle.State.RESUMED);
if (f1.isVisible()){
fragmentTransaction.hide(f1).setMaxLifecycle(f1, Lifecycle.State.CREATED);
}
}
fragmentTransaction.commitNowAllowingStateLoss();
Log.i(TAG, "onCreate: " + mFragmentManager.getFragments().size());
});
}
}
关键代码在于:
if (!f1.isVisible()){
fragmentTransaction.show(f1).setMaxLifecycle(f1, Lifecycle.State.RESUMED);
if (f2.isVisible()){
fragmentTransaction.hide(f2).setMaxLifecycle(f2, Lifecycle.State.CREATED);
}
}else if (!f2.isVisible()){
fragmentTransaction.show(f2).setMaxLifecycle(f2, Lifecycle.State.RESUMED);
if (f1.isVisible()){
fragmentTransaction.hide(f1).setMaxLifecycle(f1, Lifecycle.State.CREATED);
}
}
这边状态可以传入:Lifecycle.State.CREATED、Lifecycle.State.STARTED、Lifecycle.State.RESUME
传入Lifecycle.State.DESTORYED、Lifecycle.State.INITIALIZED 会报错。

fragmentTransaction.hide(f2).setMaxLifecycle(f2, Lifecycle.State.CREATED);对应的log
2022-06-29 10:31:17.632 10472-10472/com.example.demo D/FragmentManager: movefrom RESUMED: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:17.633 10472-10472/com.example.demo I/Fragment2: onPause:
2022-06-29 10:31:17.634 10472-10472/com.example.demo D/FragmentManager: movefrom STARTED: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:17.636 10472-10472/com.example.demo I/Fragment2: onStop:
2022-06-29 10:31:17.637 10472-10472/com.example.demo D/FragmentManager: movefrom ACTIVITY_CREATED: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:17.649 10472-10472/com.example.demo D/FragmentManager: movefrom CREATE_VIEW: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
fragmentTransaction.show(f2).setMaxLifecycle(f2, Lifecycle.State.RESUMED);对应的log
2022-06-29 10:31:26.256 10472-10472/com.example.demo D/FragmentManager: moveto CREATE_VIEW: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:26.258 10472-10472/com.example.demo I/Fragment2: onCreateView:
2022-06-29 10:31:26.280 10472-10472/com.example.demo I/Fragment2: onViewCreated:
2022-06-29 10:31:26.282 10472-10472/com.example.demo D/FragmentManager: moveto ACTIVITY_CREATED: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:26.283 10472-10472/com.example.demo D/FragmentManager: moveto RESTORE_VIEW_STATE: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:26.286 10472-10472/com.example.demo D/FragmentManager: moveto STARTED: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:26.286 10472-10472/com.example.demo I/Fragment2: onStart:
2022-06-29 10:31:26.299 10472-10472/com.example.demo D/FragmentManager: moveto RESUMED: Fragment2{956426b} (fcf2cfed-3d42-44be-9466-1d6170956877 id=0x7f080082 tag=fragment2)
2022-06-29 10:31:26.300 10472-10472/com.example.demo I/Fragment2: onResume:

可以看到生命周期从onCreatView开始走,因为view的加载也会重新走,所以效果不大。但是如果是将生命周期改成这样,可以看到fragment只走了onPause,再一次show时走了onResume,少做了很多事情。
if (!f1.isVisible()){
fragmentTransaction.show(f1).setMaxLifecycle(f1, Lifecycle.State.RESUMED);
if (f2.isVisible()){
fragmentTransaction.hide(f2).setMaxLifecycle(f2, Lifecycle.State.STARTED);
}
}else if (!f2.isVisible()){
fragmentTransaction.show(f2).setMaxLifecycle(f2, Lifecycle.State.RESUMED);
if (f1.isVisible()){
fragmentTransaction.hide(f1).setMaxLifecycle(f1, Lifecycle.State.STARTED);
}
}

2022-06-29 10:45:27.769 11190-11190/com.example.demo D/FragmentManager: movefrom RESUMED: Fragment2{956426b} (c694ebf8-2a32-4a8a-9748-09520ca42a21 id=0x7f080082 tag=fragment2)
2022-06-29 10:45:27.770 11190-11190/com.example.demo I/Fragment2: onPause:
2022-06-29 10:45:45.381 11190-11190/com.example.demo D/FragmentManager: moveto RESUMED: Fragment2{956426b} (c694ebf8-2a32-4a8a-9748-09520ca42a21 id=0x7f080082 tag=fragment2)
2022-06-29 10:45:45.382 11190-11190/com.example.demo I/Fragment2: onResume:
那如果不设置生命周期呢,操作show,hide就没有任何生命周期上的变化了,仅仅是将fragment所在的view设置为gone,或者visible。