应用后台进程被杀时,如何保存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
相关产品推荐
相关产品推荐

