Android 在片段之间共享数据的更好方法是什么?

Android 在片段之间共享数据的更好方法是什么?,android,android-fragments,android-architecture-components,android-viewmodel,android-safe-args,Android,Android Fragments,Android Architecture Components,Android Viewmodel,Android Safe Args,我想从一个片段到另一个片段共享几个整数值。我不想在设备更改配置时丢失数据 因此,我遇到了两种方法,希望知道哪一种更适合我的用例: 1.在多个片段之间共享ViewModel 2.使用SafeArgs和自定义ViewModelProvider.Factory的组合 使用SafeArgs将数据作为参数传递给导航操作,从片段a传递到另一个片段集B。为片段B实现ViewModel参数化和ViewModelFactory类。将数据从SafeArgs传递到ViewModelFactory,以使用ViewMod

我想从一个片段到另一个片段共享几个整数值。我不想在设备更改配置时丢失数据

因此,我遇到了两种方法,希望知道哪一种更适合我的用例:

1.在多个片段之间共享ViewModel 2.使用SafeArgs和自定义ViewModelProvider.Factory的组合 使用SafeArgs将数据作为参数传递给导航操作,从片段a传递到另一个片段集B。为片段B实现ViewModel参数化和ViewModelFactory类。将数据从SafeArgs传递到ViewModelFactory,以使用ViewModelProvider创建ViewModel

大概是这样的:

class B : Fragment() {

    //Seperate classes for ViewModelB & ViewModelFactoryB
    private lateinit var viewModel: ViewModelB
    private lateinit var viewModelFactory: ViewModelFactoryB

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {

        val binding: BFragmentBinding = DataBindingUtil.inflate(
                inflater,
                R.layout.b_fragment,
                container,
                false
        )

        viewModelFactory = ViewModelFactoryB(BFragmentArgs.fromBundle(requireArguments()).data)
        viewModel = ViewModelProvider(this, viewModelFactoryB).get(ViewModelB::class.java)

        return binding.root
    }
}

这完全取决于您的用例、片段之间共享的数据以及如何使用这些数据

尽管两种情况都支持传递自定义对象,但必须考虑一些事情。

对于导航组件,关于自定义对象:

数据必须是可打包的首选数据或可序列化的数据; 使用Bundle对象传递的所有数据都有其自身的局限性,并且数据量大,可能导致TransactionTooLargeException。在使用共享视图模型时,可以很容易地避免这种情况。 对于共享视图模型:

你必须定义新的类来包装你的模型; 您必须添加新的类成员以保存共享视图模型; 共享视图模型将占用内存,直到活动完成或视图模型存储被清除。 那么答案是什么呢? 这样的问题导致了自以为是的答案,但我认为在选择介于./p>之间时会用到一组提示。 在以下情况下使用安全参数:

数据量小; 使用此数据后,不需要将结果返回到上一个片段; 当您处理完这些数据时,您不在乎这些数据是否已从内存中删除,并且每次都必须再次查询它。 在以下情况下使用共享视图模型:

数据相对较大,或者您认为它可能较大; 您有多个数据模型/集; 使用此数据后确实需要将结果返回到上一个片段时; 当数据查询成本很高时。共享视图模型的寿命通常与活动的寿命相同。
这完全取决于您的用例、片段之间共享的数据以及如何使用这些数据

尽管两种情况都支持传递自定义对象,但必须考虑一些事情。

对于导航组件,关于自定义对象:

数据必须是可打包的首选数据或可序列化的数据; 使用Bundle对象传递的所有数据都有其自身的局限性,并且数据量大,可能导致TransactionTooLargeException。在使用共享视图模型时,可以很容易地避免这种情况。 对于共享视图模型:

你必须定义新的类来包装你的模型; 您必须添加新的类成员以保存共享视图模型; 共享视图模型将占用内存,直到活动完成或视图模型存储被清除。 那么答案是什么呢? 这样的问题导致了自以为是的答案,但我认为在选择介于./p>之间时会用到一组提示。 在以下情况下使用安全参数:

数据量小; 使用此数据后,不需要将结果返回到上一个片段; 当您处理完这些数据时,您不在乎这些数据是否已从内存中删除,并且每次都必须再次查询它。 在以下情况下使用共享视图模型:

数据相对较大,或者您认为它可能较大; 您有多个数据模型/集; 使用此数据后确实需要将结果返回到上一个片段时; 当数据查询成本很高时。共享视图模型的寿命通常与活动的寿命相同。
当你问最好的,但你没有提到在哪种情况下,每个即将到来的答案可能是基于每个人如何看待它的偏见。但我认为这是一个很好的开始,你看到这一页。我希望我的问题现在能清楚地解释我的用例。很抱歉,之前没有恰当地描述它。当你要求最好的答案,但没有提到在哪种情况下,每个即将到来的答案可能会基于每个人对它的看法而产生偏见。但我认为这是一个很好的开始,你看到这一页。我希望我的问题现在能清楚地解释我的用例。很抱歉,之前没有正确地阐述问题。很抱歉,没有正确地阐述问题。我想知道如何在这两种方式中做出选择,你的回答正好解释了这一点。谢谢你的回答。@VanditGoel,不客气。我想分享一些从FragmentA到FragmentB的整数值,所以我分享的数据很小。为了使用SafeArgs,我必须为FragmentB分别创建ViewModelFactory和ViewModel,并将整数从Bundle传递到ViewModel factory。虽然如果在这些片段之间共享ViewModel,我将避免所有这些代码。您建议我继续做什么?对于安全参数,您不需要任何与ViewModel相关的类。您需要使用导航com
在导航图中,您应该定义两个参数。然后在接收方片段中,可以使用MyFragmentArgs.FromBundleGetGuments.get[variable_name_here];获取传入的值。然后使用视图模型。它将更容易使用。链接旁边的主题中有一小段代码。这就是设置和访问从一个片段到另一个片段的数据所需的全部。很抱歉,没有正确地构建问题的框架。我想知道如何在这两种方式中做出选择,你的回答正好解释了这一点。谢谢你的回答。@VanditGoel,不客气。我想分享一些从FragmentA到FragmentB的整数值,所以我分享的数据很小。为了使用SafeArgs,我必须为FragmentB分别创建ViewModelFactory和ViewModel,并将整数从Bundle传递到ViewModel factory。虽然如果在这些片段之间共享ViewModel,我将避免所有这些代码。您建议我继续做什么?对于安全参数,您不需要任何与ViewModel相关的类。您需要使用导航组件,并在导航图中定义两个参数。然后在接收方片段中,可以使用MyFragmentArgs.FromBundleGetGuments.get[variable_name_here];获取传入的值。然后使用视图模型。它将更容易使用。链接旁边的主题中有一小段代码。这就是从一个片段到另一个片段设置和访问数据所需的全部。
class B : Fragment() {

    //Seperate classes for ViewModelB & ViewModelFactoryB
    private lateinit var viewModel: ViewModelB
    private lateinit var viewModelFactory: ViewModelFactoryB

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {

        val binding: BFragmentBinding = DataBindingUtil.inflate(
                inflater,
                R.layout.b_fragment,
                container,
                false
        )

        viewModelFactory = ViewModelFactoryB(BFragmentArgs.fromBundle(requireArguments()).data)
        viewModel = ViewModelProvider(this, viewModelFactoryB).get(ViewModelB::class.java)

        return binding.root
    }
}