如何使用 SavedStateHandle 和导航安全参数

ccd*_*ccd 9 performance android parameter-passing

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

Ale*_*kin 6

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

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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")
    }
}
Run Code Online (Sandbox Code Playgroud)

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

class FooViewModel @ViewModelInject constructor(
    @Assisted savedStateHandle: SavedStateHandle
) : ArgsViewModel(savedStateHandle) {

    private val args: FooFragmentArgs by navArgs()
}
Run Code Online (Sandbox Code Playgroud)


ake*_*lix 5

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

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

SafeArgs.fromSavedStateHandle(savedStateHandle)
Run Code Online (Sandbox Code Playgroud)

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

  • `MyFragmentArgs.fromSavedStateHandle(savedStateHandle)` 自 safe args 2.4.0 起可用 (4认同)