- 原文地址:Locale changes and the AndroidViewModel antipattern
- 原文做者:Jose Alcérreca
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:solerji
TL;DR:从视图模型中公开资源 ID 以免显示废弃的数据。前端
在 ViewModel 中,若是要公开来自资源(字符串、可绘制文件、颜色……)的数据,则必须着重考虑 ViewModel 对象而忽视配置更改,例如区域设置更改。当用户更改其区域设置时,活动将从新被建立,但不建立 ViewModel 对象。android
AndroidViewModel
是已知应用程序上下文的 ViewModel
的子类。然而,若是您没有注意到或没有对上下文的生命周期作出反应,访问上下文多是危险的。建议的作法是避免处理在 ViewModels 中具备生命周期的对象。ios
让咱们看看跟踪器中基于此问题的示例:在系统区域设置更改时更新 ViewModel 。git
// 别这么作
public class MyViewModel extends AndroidViewModel {
public final MutableLiveData<String> statusLabel = new MutableLiveData<>();
public SampleViewModel(Application context) {
super(context);
statusLabel.setValue(context.getString(R.string.labelString));
}
}
复制代码
问题的关键是字符串在构造器中只解释一次。若是有区域设置更改,则不会从新建立视图模型。这将致使咱们的应用程序显示废弃的数据,所以只能部分本地化。github
正如 Sergey 在评论中指出的那样 comments,推荐的方法是公开要加载的资源的 ID ,并在视图中这样作。因为视图(活动、片断等)具备生命周期意识,所以它将在配置更改后从新建立,以便正确地从新加载资源。后端
// 显示资源ID
public class MyViewModel extends ViewModel {
public final MutableLiveData<Int> statusLabel = new MutableLiveData<>();
public final MutableLiveData<Int> statusLabel = new MutableLiveData<>();
public SampleViewModel(Application context) {
super(context);
statusLabel.setValue(R.string.labelString);
}
}
复制代码
即便你不打算本地化你的应用程序,它也会使测试变得更容易而且清空你的 ViewModel 对象,所以没有理由不去考虑它的前瞻性。架构
咱们在以 Java 为基础的 Android 架构存储库中解决了这个问题 Java 以及在Kotlin 分支上。咱们也把资源转移到 数据绑定布局。布局
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。区块链
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。测试