You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

应用后台进程被杀时,如何保存Fragment中的Lambda类型?

解决Fragment进程被杀时保存并恢复Lambda的方案

Lambda本质是匿名内部类,无法直接序列化存入onSaveInstanceState,核心思路是将Lambda的逻辑转化为可持久化的标识,或借助生命周期组件管理,以下是三种可行方案:

方案一:用枚举标识Lambda逻辑

将有限的Lambda逻辑映射为枚举常量,保存枚举值,重建时根据枚举重新生成对应Lambda。适合逻辑固定、可枚举的场景。

示例代码

// 定义枚举标识不同的Lambda逻辑
enum class CallbackType : Serializable {
    ON_ITEM_CLICK, ON_REFRESH, ON_SUBMIT
}

class MyFragment : Fragment() {
    private var callback: (() -> Unit)? = null

    companion object {
        private const val KEY_CALLBACK_TYPE = "callback_type"

        fun newInstance(callbackType: CallbackType): MyFragment {
            return MyFragment().apply {
                arguments = Bundle().apply {
                    putSerializable(KEY_CALLBACK_TYPE, callbackType)
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 优先从savedInstanceState恢复(进程被杀场景),否则取arguments传入的初始值
        val callbackType = savedInstanceState?.getSerializable(KEY_CALLBACK_TYPE) as? CallbackType
            ?: arguments?.getSerializable(KEY_CALLBACK_TYPE) as? CallbackType
        
        callback = when (callbackType) {
            CallbackType.ON_ITEM_CLICK -> { /* 实现点击项的逻辑 */ }
            CallbackType.ON_REFRESH -> { /* 实现刷新逻辑 */ }
            CallbackType.ON_SUBMIT -> { /* 实现提交逻辑 */ }
            else -> null
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        // 保存当前Lambda对应的枚举标识
        val currentType = when (callback) {
            // 根据当前callback的逻辑匹配对应枚举
            else -> null
        }
        outState.putSerializable(KEY_CALLBACK_TYPE, currentType)
    }
}

方案二:封装Lambda为可序列化类

将Lambda封装到实现Serializable接口的类中,通过序列化保存。适合动态逻辑,但需注意避免持有不可序列化的引用(如Context、View等,可改用弱引用)。

示例代码

// 封装Lambda为可序列化类,用弱引用避免内存泄漏
class SerializableCallback(
    private val weakFragment: WeakReference<MyFragment>,
    private val action: (MyFragment) -> Unit
) : Serializable {
    fun execute() {
        weakFragment.get()?.let { action(it) }
    }
}

class MyFragment : Fragment() {
    private var callback: SerializableCallback? = null

    companion object {
        private const val KEY_CALLBACK = "callback"

        fun newInstance(callback: (MyFragment) -> Unit): MyFragment {
            return MyFragment().apply {
                arguments = Bundle().apply {
                    putSerializable(KEY_CALLBACK, SerializableCallback(WeakReference(this), callback))
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        callback = if (savedInstanceState != null) {
            savedInstanceState.getSerializable(KEY_CALLBACK) as? SerializableCallback
        } else {
            arguments?.getSerializable(KEY_CALLBACK) as? SerializableCallback
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putSerializable(KEY_CALLBACK, callback)
    }
}

方案三:借助ViewModel管理Lambda

ViewModel在进程被杀重建时会自动保留,将Lambda存入ViewModel,Fragment重建时直接获取即可。最适合生命周期绑定的回调场景,但需注意避免Lambda持有Fragment的强引用。

示例代码

class MyViewModel : ViewModel() {
    var callback: (() -> Unit)? = null
}

class MyFragment : Fragment() {
    private val viewModel by viewModels<MyViewModel>()

    companion object {
        private const val KEY_CALLBACK_TYPE = "callback_type"

        fun newInstance(callbackType: CallbackType): MyFragment {
            return MyFragment().apply {
                arguments = Bundle().apply {
                    putSerializable(KEY_CALLBACK_TYPE, callbackType)
                }
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 仅在首次创建时初始化Lambda,重建时ViewModel已保留该值
        if (viewModel.callback == null) {
            val callbackType = arguments?.getSerializable(KEY_CALLBACK_TYPE) as? CallbackType
            viewModel.callback = when (callbackType) {
                CallbackType.ON_ITEM_CLICK -> { /* 对应逻辑 */ }
                CallbackType.ON_REFRESH -> { /* 对应逻辑 */ }
                else -> null
            }
        }
        // 使用viewModel.callback即可
    }
}

方案对比

  • 枚举标识:实现简单,无序列化风险,但仅支持固定逻辑。
  • 可序列化封装类:支持动态逻辑,但需严格处理引用避免泄漏或序列化失败。
  • ViewModel方案:无需手动处理保存恢复,生命周期友好,推荐用于与UI绑定的回调场景。

内容的提问来源于stack exchange,提问作者user23316878

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:07:21