Android Dagger 2注入ViewModel奇数行为(屏幕旋转时不重复使用ViewModel)

Android Dagger 2注入ViewModel奇数行为(屏幕旋转时不重复使用ViewModel),android,mvvm,android-lifecycle,dagger-2,Android,Mvvm,Android Lifecycle,Dagger 2,在将ViewModels注入到我的活动/片段中时,我注意到了一个奇怪的行为(遵循中的示例) 试用版1起初,我只是懒洋洋地看看使用时会发生什么 @Inject MainViewModel viewModel; 显然,我为每个活动和旋转时都获得了一个新的MainViewModel实例 试用版2 然后,我更新为使用“正确的方法”,注入ViewModelProvider.Factory,并在onCreate中获取视图模型: @Inject ViewModelProvider.Factory viewM

在将ViewModels注入到我的活动/片段中时,我注意到了一个奇怪的行为(遵循中的示例)

试用版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我更新了我的主要活动模块,包括以下内容:

@Provides @ActivityScope
public MainViewModel provideMainViewModel(MainActivity activity,
        ViewModelProvider.Factory factory) {
    return ViewModelProviders.of(activity, factory).get(MainViewModel::class);
}
这导致了一个新的MainViewModel实例,甚至在屏幕上旋转(与试用版1相同)。我验证了提供的ViewModelProvider.Factory实例在每次调用ProviderMainViewModel时都是相同的。我还尝试删除@ActivityScope,这会导致更奇怪的行为,特别是在尝试在MainActivity和MainFragment1中包含相同的MainViewModel实例时。片段获得了与旋转前相同的MainViewModel实例,但活动获得了一个全新的实例,尽管对provideMainViewModel的两个调用都是使用相同的MainActivity实例和工厂调用的

问题有人能解释一下吗?我没有办法将ViewModel直接注入到我的活动/片段中吗

更新

这真的让我很困惑,所以我已经更新了这个问题的完整示例。注意,我必须更新AppInjector的
FragmentLifecycleCallback
,以便在
onFragmentPreCreated
期间注入片段。这是由于片段的生命周期,使用
SearchViewModel
SearchFragment
中看到的当前实现将在
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

我可能错了,但因为工厂是在ActivityScope级别进行注释的,所以活动的每个新实例都将有一个不同的提供程序实例,这反过来将创建视图模型的一个新实例。我将注入工厂,在ApplicationScope中对其进行注释(因为我们希望保留),然后使用它来获取视图模型的实例。

工厂正在使用
@Singleton
注释(),因为您的MainActivityProvidersModule通过静态创建(或重用)的提供程序提供视图模型。与恢复工厂本身相反,您似乎在尝试两个方面都做到最好,这与创建系统的方式不兼容。我将使用ViewModelProvidersOf模式获取工厂,将其放在ActivityScope,然后从中创建ViewModel