想象 Android 系统是一个神奇的木偶剧场:
- 🏰 Activity 是舞台本身
- 🎭 Fragment 是舞台上的提线木偶
- 🎛️ FragmentManager 是中央控制台
- 📡 LifecycleOwner 是舞台的信号发射塔
让我们揭开中央控制台如何监听舞台信号的神秘面纱!
📡 信号连接系统
java
// 舞台(Activity)启动时
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 秘密:控制台自动连接信号塔
getSupportFragmentManager().attachController(
new FragmentController(this), // 控制器
new FragmentHostCallback<>(this), // 宿主回调
this // 生命周期信号塔
);
}
}
// 控制台内部连接代码
void attachController(FragmentController controller,
FragmentHostCallback host,
LifecycleOwner lifecycleOwner) {
// 1. 绑定舞台信号塔
mLifecycleOwner = lifecycleOwner;
// 2. 注册生命周期监听器
lifecycleOwner.getLifecycle().addObserver(new LifecycleObserver() {
@State(Lifecycle.State.ON_CREATE)
void onCreate() {
dispatchStateChange(Fragment.CREATED);
}
@State(Lifecycle.State.ON_START)
void onStart() {
dispatchStateChange(Fragment.STARTED);
}
// ... 其他状态监听
});
}
📶 信号传递机制
当舞台状态变化时:
java
// 信号塔核心(LifecycleRegistry)
public class ComponentActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
protected void onCreate(Bundle s) {
super.onCreate(s);
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
protected void onStart() {
super.onStart();
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
// ... 其他生命周期
}
控制台接收信号后的处理:
java
// FragmentManager 的状态分发
void dispatchStateChange(int nextState) {
// 1. 更新控制台自身状态
mCurState = nextState;
// 2. 通知所有木偶更新状态
for (Fragment fragment : mFragments) {
moveFragmentToExpectedState(fragment);
}
// 3. 执行待处理操作
execPendingActions();
}
🧩 状态同步流程图解
text
舞台状态变化 → 信号塔广播 → 控制台接收 → 更新木偶状态
(Activity) (Lifecycle) (FragmentManager) (Fragment)
具体信号转换表:
舞台信号 (Activity) | 控制台接收事件 | 木偶状态 (Fragment) |
---|---|---|
onCreate() | ON_CREATE | CREATED |
onStart() | ON_START | STARTED |
onResume() | ON_RESUME | RESUMED |
onPause() | ON_PAUSE | STARTED |
onStop() | ON_STOP | CREATED |
onDestroy() | ON_DESTROY | INITIALIZING |
⚙️ 木偶状态更新引擎
控制台如何精确更新每个木偶的状态:
java
void moveFragmentToExpectedState(Fragment f) {
// 计算目标状态
int targetState = Math.min(f.getMaxState(), mCurState);
// 状态升级路径
if (f.mState < targetState) {
switch (f.mState) {
case Fragment.INITIALIZING:
if (targetState >= Fragment.ATTACHED) {
f.onAttach(f.mHost.getContext()); // 连接舞台
}
case Fragment.ATTACHED:
if (targetState >= Fragment.CREATED) {
f.performCreate(f.mSavedFragmentState); // 创建核心
}
// ... 其他状态升级
}
}
// 状态降级路径
else if (f.mState > targetState) {
switch (f.mState) {
case Fragment.RESUMED:
if (targetState < Fragment.RESUMED) {
f.performPause(); // 暂停表演
}
// ... 其他状态降级
}
}
}
🌪️ 处理特殊场景
场景1:舞台旋转重建
java
// 舞台保存状态时
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// 控制台保存木偶状态
FragmentManagerState fms = saveAllState();
outState.putParcelable("android:support:fragments", fms);
}
// 重建舞台时
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
// 控制台恢复木偶状态
FragmentManagerState fms = savedInstanceState.getParcelable("android:support:fragments");
getSupportFragmentManager().restoreSaveState(fms);
}
}
场景2:后台返回前台
java
// 舞台从后台返回
protected void onStart() {
super.onStart(); // 发送ON_START信号
// 控制台内部:
// 1. 检查需要恢复的Fragment
// 2. 调用moveToState(Fragment.STARTED)
// 3. 触发Fragment的onStart()
}
🔌 信号中断处理
当控制台失去信号连接时:
java
// 舞台销毁时
protected void onDestroy() {
super.onDestroy();
// 控制台断开连接
getSupportFragmentManager().dispatchDestroy();
}
// 控制台内部
void dispatchDestroy() {
// 1. 停止监听信号
mLifecycleOwner.getLifecycle().removeObserver(this);
// 2. 销毁所有木偶
for (Fragment f : mFragments) {
moveFragmentToExpectedState(f, Fragment.INITIALIZING);
f.onDetach(); // 切断提线
}
// 3. 清理资源
mFragments.clear();
}
💡 控制台监听技巧
- 精确状态匹配:
java
// 检查当前舞台状态
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
// 安全更新Fragment
}
- 避免信号干扰:
kotlin
// 在正确时机提交事务
lifecycleScope.launch {
// 等待舞台准备就绪
repeatOnLifecycle(Lifecycle.State.STARTED) {
// 安全执行Fragment操作
commitFragmentTransaction()
}
}
- 处理信号丢失:
java
public void onViewCreated(View view, Bundle s) {
super.onViewCreated(view, s);
// 检查舞台是否有效
if (getActivity() == null || isRemoving()) {
return; // 安全退出
}
// 正常初始化
}
🎯 监听系统全景图
text
舞台 (Activity)
│
▼
信号发射塔 (LifecycleOwner)
│
▼
信号接收器 (LifecycleObserver)
│
▼
中央控制台 (FragmentManager)
│
├─▶ 木偶A (Fragment)
├─▶ 木偶B (Fragment)
└─▶ 木偶C (Fragment)
终极测验:当舞台进入后台(onStop)后立即旋转屏幕,控制台如何处理?
答案:
- 首先收到 ON_STOP 信号,将木偶状态降级到 CREATED
- 收到配置变更信号,保存木偶状态到 Bundle
- 销毁当前舞台和信号连接
- 创建新舞台,重新连接信号
- 从 Bundle 恢复木偶状态
- 根据新舞台状态更新木偶
通过这套精密的信号监听系统,FragmentManager 实现了与 Activity 生命周期的完美同步,确保每个 Fragment 木偶都能在正确的时机表演正确的动作!