我注意到在将ViewModel注入我的活动/片段时出现奇怪的行为(遵循GithubBrowserSample处的示例)。
试用1 起初我只是懒得看看使用时会发生什么
@Inject MainViewModel viewModel;
显然,我为每个活动和旋转时都获得了MainViewModel的新实例。
试用2
然后我更新为使用“正确的方式”注入ViewModelProvider.Factory
并抓取onCreate
中的视图模型:
@Inject ViewModelProvider.Factory viewModelProviderFactory;
private MainViewModel viewModel;
@Override
public void onCreate(Bundle savedInstanceState) {
viewModel = ViewModelProviders.of(this, viewModelProviderFactory)
.get(MainViewModel::class);
}
这个片段就像一个魅力。打印viewModel将显示我为从startActivity调用触发但在旋转时重新使用的每个新活动实例获取新实例。这让我想到了...也许我可以注入MainViewModel。
试用版3 我更新了我的MainActivityModule以包含以下内容:
@Provides @ActivityScope
public MainViewModel provideMainViewModel(MainActivity activity,
ViewModelProvider.Factory factory) {
return ViewModelProviders.of(activity, factory).get(MainViewModel::class);
}
这导致了MainViewModel的新实例,即使在屏幕旋转上也是如此(与试验1相同)。我验证了每次调用provideMainViewModel时提供的ViewModelProvider.Factory实例都是相同的。我还尝试删除@ActivityScope,这会导致更奇怪的行为,尤其是在尝试在MainActivity和MainFragment1中包含相同的MainViewModel实例时。该片段获得了与旋转之前相同的MainViewModel实例,但是活动得到了一个全新的,即使调用了provideMainViewModel都使用相同的MainActivity实例和工厂调用。
问题任何人都可以解释一下吗?我没办法将ViewModel直接注入我的activity / fragment吗?
更新
这真让我感到困惑所以我已经更新,以包含问题HERE的完整示例。请注意,我必须更新AppInjector的FragmentLifecycleCallback
以在onFragmentPreCreated
期间注入片段。这是由于片段的生命周期而完成的,使用SearchFragment
在SearchViewModel
中看到的当前实现将在onActivityCreated
期间获取视图模型的实例,该实例可能会被调用多次相同的片段。在这种情况下,将从ViewModelProviders
返回相同的视图模型,并将注册多个观察者。而应该在onCreate
之前注入片段,并且应该在那时注册任何LiveData观察者。
运行并旋转时,您将看到以下日志:
12-19 22:48:28.538 7116-7116/com.android.example.github D/MainActivityProvidersMo: provideMainViewModel for com.android.example.github.MainActivity@78c5d27 using com.android.example.github.viewmodel.GithubViewModelFactory@6d6c140: com.android.example.github.MainViewModel@fd1f879
12-19 22:48:28.611 7116-7116/com.android.example.github D/MainActivity: viewModel: com.android.example.github.MainViewModel@fd1f879
12-19 22:48:28.615 7116-7116/com.android.example.github D/dagger.android.support: An injector for com.android.example.github.ui.search.SearchFragment was found in com.android.example.github.MainActivity
12-19 22:48:28.616 7116-7116/com.android.example.github D/SearchFragment: mainViewModel: com.android.example.github.MainViewModel@fd1f879
12-19 22:48:28.760 7116-7116/com.android.example.github D/SearchFragment: results live data has observers? false
12-19 22:48:40.579 7116-7116/com.android.example.github D/MainActivityProvidersMo: provideMainViewModel for com.android.example.github.MainActivity@d1f344f using com.android.example.github.viewmodel.GithubViewModelFactory@6d6c140: com.android.example.github.MainViewModel@c5387dc
12-19 22:48:40.581 7116-7116/com.android.example.github D/dagger.android.support: An injector for com.android.example.github.ui.search.SearchFragment was found in com.android.example.github.MainActivity
12-19 22:48:40.583 7116-7116/com.android.example.github D/SearchFragment: mainViewModel: com.android.example.github.MainViewModel@c5387dc
12-19 22:48:40.625 7116-7116/com.android.example.github D/MainActivity: viewModel: com.android.example.github.MainViewModel@c5387dc
12-19 22:48:40.715 7116-7116/com.android.example.github D/SearchFragment: results live data has observers? false
答案 0 :(得分:0)
我可能错了,但由于Factory在ActivityScope级别进行了注释,因此每个活动的新实例都会有一个不同的提供者实例,而后者将创建一个新的视图模型实例。我会注入Factory,在ApplicationScope上注释它(因为我们希望保留),然后用它来获取视图模型的实例。