【问题标题】:How to use SavedStateHandle and navigation Safe Args如何使用 SavedStateHandle 和导航安全参数
【发布时间】:2020-12-24 09:31:30
【问题描述】:

我有两个选项可以在片段之间传递数据,导航的安全参数和视图模型的 SavedStateHandle,它们之间有什么区别以及如何在正确的位置使用它们?

【问题讨论】:

    标签: android performance parameter-passing


    【解决方案1】:

    关于这个问题的讨论很少。 android ViewModelFactory with hilt https://issuetracker.google.com/issues/136967621

    对我来说,最明显的解决方案是使用类似

    SafeArgs.fromSavedStateHandle(savedStateHandle)
    

    但现在,我使用的是字符串键。

    【讨论】:

    • MyFragmentArgs.fromSavedStateHandle(savedStateHandle) 自安全参数 2.4.0 起可用
    • @Tom 2.4.0-rc01 如果更正确,还没有稳定版本developer.android.com/jetpack/androidx/releases/…
    • @user924 昨天稳定了:)
    • @Tom 这很有趣 :) 它在最新的 studio 和 gradle 插件版本中能正常工作吗?
    • @user924 我认为确实如此,不幸的是我无法测试它,因为我的项目是一个黑暗时代的依赖,它阻止我超越 2.3.0-alpha04
    【解决方案2】:

    如果您使用 hilt,您可以像这样将传入的参数包装在片段(和其他组件)中

    open class BaseFragment : Fragment() { // Inherit your fragment from this
    
        override fun setArguments(args: Bundle?) {
            if (args != null) {
                if (args.getBundle(BUNDLE_ARGS) != null) {
                    super.setArguments(args)
                } else {
                    super.setArguments(Bundle(args).apply {
                        putBundle(BUNDLE_ARGS, args) // Wrap the arguments as BUNDLE_ARGS
                    })
                }
            } else {
                super.setArguments(null)
            }
        }
    }
    

    然后对于视图模型,您可以从类似的东西继承

    open class ArgsViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    
        val arguments get() = savedStateHandle.get<Bundle>(BUNDLE_ARGS)
    
        @MainThread
        inline fun <reified Args : NavArgs> navArgs() = NavArgsLazy(Args::class) {
            arguments ?: throw IllegalStateException("ViewModel $this has null arguments")
        }
    }
    

    然后像使用安全参数一样使用它

    class FooViewModel @ViewModelInject constructor(
        @Assisted savedStateHandle: SavedStateHandle
    ) : ArgsViewModel(savedStateHandle) {
    
        private val args: FooFragmentArgs by navArgs()
    }
    

    【讨论】:

    • 我们遇到了这个实现的问题。当 Android 框架尝试将 Bundle 写入 Parcel 时,有时会导致堆栈溢出。
    • 我没有注意到任何与此实现相关的崩溃报告,但我不怀疑可能存在问题。操作系统写入导致 stackoverflow 的包听起来不像是这个特定方法的实现问题,但是你去吧。无论哪种方式,使用 androidx-navigation-2.4.0 都会有更好的处理方式,所以请保持原样 - 我会尽量记住更新答案
    • 抱歉,没注意到Bundle(args)。在我们的例子中,有人明确地将args 放入args。那你的回答就OK了。
    猜你喜欢
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多