作者:马丁乐_449 | 来源:互联网 | 2022-12-10 05:43
我试图在我的Android应用程序中实现MVVM模式.我已经读过ViewModels不应该包含任何特定于Android的代码(以使测试更容易),但是我需要使用上下文来处理各种事情(从xml获取资源,初始化首选项等).做这个的最好方式是什么?我看到它AndroidViewModel
有一个对应用程序上下文的引用,但是它包含特定于android的代码,因此我不确定它是否应该在ViewModel中.这些也与Activity生命周期事件有关,但我使用匕首来管理组件的范围,所以我不确定这会如何影响它.我是MVVM模式和Dagger的新手,所以任何帮助都表示赞赏!
1> 小智..:
您可以使用Application
它通过提供的上下文AndroidViewModel
,你应该继承AndroidViewModel
这简直是一个ViewModel
包含一个Application
参考.
2> 小智..:
并不是ViewModels不应该包含Android特定的代码来使测试更容易,因为它是使测试更容易的抽象.
ViewModel之所以不应该包含Context的实例或类似于上下文的其他对象的原因是因为它具有与活动和片段不同的生命周期.
我的意思是,假设您在应用上进行了轮换更改.这会导致您的Activity和Fragment自行销毁,因此它会重新创建.ViewModel意味着在此状态期间保持不变,因此如果它仍然在被破坏的Activity中持有View或Context,则可能会发生崩溃和其他异常.
至于你应该怎么做你想做的事情,MVVM和ViewModel与JetPack的数据绑定组件配合得非常好.对于大多数情况,您通常会存储String,int或etc等,您可以使用Databinding使Views直接显示它,因此不需要将值存储在ViewModel中.
但是如果你不想要Databinding,你仍然可以在构造函数或方法中传递Context来访问Resources.只是不要在ViewModel中包含该Context的实例.
3> devDeejay..:
对于Android体系结构组件视图模型,
将您的活动上下文传递给活动的ViewModel作为内存泄漏不是一个好习惯。
因此,要在您的ViewModel中获取上下文,ViewModel类应扩展Android View Model类。这样,您可以获取上下文,如下面的示例代码所示。
class ActivityViewModel(application: Application) : AndroidViewModel(application) {
private val cOntext= getApplication().applicationContext
//... ViewModel methods
}
4> Vincent Will..:
我最终做的不是直接在ViewModel中使用Context,而是创建了像ResourceProvider这样的提供程序类,它可以为我提供所需的资源,并且我将这些提供程序类注入到我的ViewModel中
5> Alessandro C..:
您可以getApplication().getApplicationContext()
从ViewModel中访问应用程序上下文。这是访问资源,首选项等所需的。
ViewModel类没有getApplication方法。
不,但是`AndroidViewModel`可以
6> 小智..:
简短答案-不要这样做
为什么呢
它破坏了视图模型的全部目的
通过使用LiveData实例和各种其他推荐的方法,您几乎可以在视图模型中做的所有事情都可以在活动/片段中完成。