【问题标题】:Why does ViewModelProvider creates new instance of view model on screen rotation?为什么 ViewModelProvider 会在屏幕旋转时创建新的视图模型实例?
【发布时间】:2020-06-06 04:30:26
【问题描述】:

我正在尝试实现分页,但每次我旋转视图模型的屏幕构造函数时都会被调用,从而触发 loadInitial 以从我的 DataSource 类中的网络获取新数据。感谢帮助

// ViewModel
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"

在我的 oncreate 活动中:

TopRatedResultViewModel viewModel =   ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()).create(TopRatedResultViewModel.class);

查看模型:

public class TopRatedResultViewModel extends AndroidViewModel {
private Top_Rated_Results_Repository repository;

public TopRatedResultViewModel(@NonNull Application application) {
    super(application);
    Log.d("moviedatabaselog", "TopRatedResultViewModel ");
    repository = new Top_Rated_Results_Repository(application);

}

public LiveData<PagedList<Top_Rated_Result>> getTopRatedResultsPagedList() {
    return repository.getTopRatedResultsPagedList();
}

我正在关注本教程Android paging with retrofit 但是这里使用了已弃用的 ViewModelProviders.of 并且当我在屏幕旋转构造函数后测试它时不会被调用。

【问题讨论】:

  • 您是否在清单中为该特定活动添加了 configchanges,如果没有,则添加 android:configChanges="orientation|screenSize"
  • @AshishSharma ViewModel 类允许数据在配置更改后继续存在。因此,即使 onDestroy() 和 onCreate() 活动在配置更改时发生,ViewModel 的实例也不会被销毁或垃圾​​收集。你应该看看 jetpack 架构组件...

标签: android android-livedata android-architecture-components android-mvvm


【解决方案1】:

您永远不应该自己调用工厂的 create() 方法 - 这将忽略任何以前创建的 ViewModel 并始终创建一个新实例,而不是只创建一个实例并在每次检索实例时重用它。

相反,您应该关注the documentation 并使用ViewModelProvider:

// By passing in your Activity/Fragment as the ViewModelStoreOwner
// ViewModelProvider is able to retrieve already existing ViewModels
// Rather than create a new one each time
ViewModelProvider viewModelProvider = new ViewModelProvider(this);

// Then you call get() on your ViewModelProvider to get the instance,
// only creating one if one doesn't already exist
TopRatedResultViewModel viewModel = viewModelProvider.get(TopRatedResultViewModel.class);

【讨论】:

  • 如果我这样使用它,我会收到以下错误:原因:java.lang.InstantiationException: java.lang.Class has no zero argument constructor .我正在扩展 AndroidView 模型,因为我需要通过构造函数传递的数据库的上下文。感谢 create() 提示。
  • 根据Lifecycle 2.2.0 release notes,如果您希望能够在默认情况下使用AndroidViewModel 和ViewModelProvider 构造函数,则需要升级到Fragment 1.2.0 或更高版本。否则,您可以将AndroidViewModelFactory 作为第二个参数传递给ViewModelProvider 构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 2020-06-26
  • 1970-01-01
相关资源
最近更新 更多