Fragment生命周期童话:提线木偶剧场

7 阅读4分钟

想象Android世界是一个神奇的木偶剧场,Activity是舞台总监,Fragment是提线木偶。木偶的每个动作都由舞台总监的提线控制,让我们揭开这场表演的幕后秘密!


🎭 第一章:舞台准备(Activity创建)

舞台总监(Activity)搭建剧场

java

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.theater_stage); // 搭建舞台
    
    // 准备木偶(Fragment实例)
    PuppetFragment puppet = new PuppetFragment();
    
    // 给木偶系上提线(FragmentTransaction)
    getSupportFragmentManager().beginTransaction()
        .add(R.id.puppet_spot, puppet) // 指定木偶位置
        .commit(); // 提交指令
}

幕后花絮
此时木偶只是被创建,还没开始表演(Fragment的onCreate()已被调用,但视图未创建)


🧵 第二章:提线控制系统

舞台总监通过神奇的生命线控制器操纵木偶:

java

// 生命线控制器核心代码(简化版)
public void performFragmentLifecycle() {
    // 当Activity执行onStart()时
    for (Fragment fragment : fragments) {
        fragment.performAttach();    // 系上提线
        fragment.performCreate();     // 激活木偶核心
        fragment.performCreateView(); // 创建木偶外观
        fragment.performViewCreated();// 装饰木偶
        fragment.performStart();      // 准备登场
    }
    
    // 当Activity执行onResume()时
    for (Fragment fragment : fragments) {
        fragment.performResume();     // 木偶开始表演
    }
}

🪀 木偶的响应(Fragment生命周期):

java

public void performAttach() {
    onAttach(context); // "提线已连接!"
    mHostActivity = (Activity) context; // 记住舞台总监
}

public void performCreateView() {
    View view = onCreateView(...); // "正在制作我的身体!"
    onViewCreated(view, ...);     // "给我的衣服绣上花纹!"
}

🎪 第三章:舞台表演(Activity运行)

场景1:正常表演流程

text

舞台总监命令          木偶动作
════════════════    ════════════════════════════════
activity.onStart() → fragment.onAttach()
                     fragment.onCreate()
                     fragment.onCreateView()
                     fragment.onViewCreated()
                     fragment.onActivityCreated()
                     fragment.onStart()
                     
activity.onResume() → fragment.onResume() [木偶开始跳舞]

场景2:临时插播广告(弹出Dialog)

java

// 舞台总监插播广告
new AlertDialog.Builder(this).show();

// 幕后发生:
activity.onPause() → fragment.onPause() 
// 木偶冻结:"广告时间,暂停跳舞!"

场景3:中场休息(Activity进入后台)

java

// 观众休息
public void onStop() {
    super.onStop(); // 舞台总监:"中场休息!"
    
    // 所有木偶依次:
    // fragment.onPause() → fragment.onStop() 
    // → fragment.onDestroyView() [部分木偶卸妆]
}

木偶日记
onDestroyView() = "暂时脱下表演服装,但随时准备重返舞台"


🌪 第四章:舞台事故(配置变更)

当剧场旋转屏幕时:

java

// 舞台总监的应急预案
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    
    // 通知所有木偶保存状态
    for (Fragment f : fragments) {
        f.saveState(outState); // 调用fragment.onSaveInstanceState()
    }
}

// 重建舞台后
public void onCreate(Bundle savedInstanceState) {
    // 恢复木偶状态
    if(savedInstanceState != null) {
        FragmentManager.restoreSaveState(savedInstanceState);
    }
}

木偶的生存技巧
onSaveInstanceState()里保存关键数据:"把舞步记录在小本本上"


🪫 第五章:更换木偶(Fragment事务)

舞台总监动态操控木偶:

java

// 替换木偶表演
getSupportFragmentManager().beginTransaction()
    .setReorderingAllowed(true) // 优化提线操作
    .replace(R.id.puppet_spot, new DanceFragment())
    .addToBackStack("dance_show") // 记录在回退栈
    .commit();

// 系统自动执行:
// 旧木偶:onPause() → onStop() → onDestroyView()
// 新木偶:onAttach() → onCreate() → onCreateView()...

提线魔法
addToBackStack() = 给当前状态拍快照,按返回键时恢复


🔚 第六章:演出结束(Activity销毁)

正常谢幕流程

text

activity.onPause() → fragment.onPause() 
activity.onStop()  → fragment.onStop()
activity.onDestroy() → {
   fragment.onDestroyView() // "脱下表演服装"
   fragment.onDestroy()     // "关闭动力核心"
   fragment.onDetach()      // "切断提线!"
}

紧急关闭剧场(系统杀进程)

java

// 木偶的最后一搏
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("last_words", "我会回来的!");
}

🧩 提线控制系统全景图

text

舞台总监(Activity)       木偶(Fragment)              关键提线动作
═══════════════════     ═══════════════════════     ═════════════════════════
onCreate()             → 创建木偶实例                new Fragment()
onStart()              → 系上提线                   performAttach()
                       → 激活核心                   performCreate()
                       → 制作身体                   performCreateView()
                       → 装饰外观                   performViewCreated()
                       → 准备登场                   performStart()
                       
onResume()             → 开始表演                   performResume()
onPause()              → 暂停动作                   performPause()
onStop()               → 退出舞台                   performStop()
onDestroy()            → 切断提线                   performDetach()

⚙️ 提线控制核心技术

  1. FragmentManager - 提线控制台

    java

    public void controlPuppets() {
        // 查找木偶
        Fragment puppet = findFragmentById(R.id.puppet_spot);
        
        // 提线操作
        fragmentManager.beginTransaction()
            .show(puppet)  // 拉起木偶
            .setCustomAnimations(...) // 添加动画
            .commit();
    }
    
  2. 生命周期状态机 - 木偶行为规则

    java

    // 状态转换核心逻辑
    void moveToState(Fragment f, int newState) {
        switch(newState) {
            case ATTACHED: f.onAttach(); break;
            case CREATED: f.onCreate(); break;
            case VIEW_CREATED: f.onCreateView(); break;
            // ...其他状态转换
        }
    }
    
  3. 视图销毁优化 - 木偶换装术

    kotlin

    // 配置View复用
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        // 魔法:复用之前的视图
        return savedInstanceState?.getParcelable("saved_view") 
               ?: inflater.inflate(R.layout.puppet_view, container, false)
    }
    

💡 木偶表演黄金法则

  1. 永远通过提线获取舞台信息

    java

    // 正确方式(在onAttach时缓存)
    private Activity mStage;
    
    public void onAttach(Context context) {
        super.onAttach(context);
        mStage = (Activity) context;
    }
    
    void dance() {
        // 使用舞台资源
        mStage.getResources().getColor(R.color.costume);
    }
    
  2. 优雅处理提线断裂(Activity销毁)

    kotlin

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // 检查舞台是否消失
        if (isRemoving || activity == null) {
            return // 安全退出
        }
        // 正常初始化
    }
    
  3. 及时清理提线连接

    java

    public void onDestroyView() {
        // 释放所有资源
        mDanceThread.quit();
        mBinding = null;
        super.onDestroyView();
    }
    

终极测验:当观众按下返回键时,木偶如何恢复之前的表演?
答案:通过addToBackStack()保存状态,FragmentManager自动执行反向生命周期调用


通过这个提线木偶剧场的故事,我们看到Fragment就像舞台上的木偶,它的每个生命周期动作都由Activity这个"舞台总监"通过FragmentManager的"提线"精确控制。掌握这套提线控制系统,你就能导演精彩的Android界面表演!